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
parent 7b1349cfe6
commit b1ced75386
29 changed files with 724 additions and 648 deletions

View file

@ -160,31 +160,6 @@ void timer0_nrf_isr(void *arg)
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : (dticks > 0));
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
/* FIXME switch to 1 MHz once this is fixed in QEMU */
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_2MHz);
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
IRQ_CONNECT(TIMER0_IRQn, 1, timer0_nrf_isr, 0, 0);
irq_enable(TIMER0_IRQn);
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_CLEAR);
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START);
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
set_comparator(counter() + CYC_PER_TICK);
}
event_clear();
NVIC_ClearPendingIRQ(TIMER0_IRQn);
int_enable();
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -255,3 +230,31 @@ uint32_t sys_clock_cycle_get_32(void)
k_spin_unlock(&lock, key);
return ret;
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
/* FIXME switch to 1 MHz once this is fixed in QEMU */
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_2MHz);
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
IRQ_CONNECT(TIMER0_IRQn, 1, timer0_nrf_isr, 0, 0);
irq_enable(TIMER0_IRQn);
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_CLEAR);
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START);
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
set_comparator(counter() + CYC_PER_TICK);
}
event_clear();
NVIC_ClearPendingIRQ(TIMER0_IRQn);
int_enable();
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -42,24 +42,6 @@ static void timer_irq_handler(const void *unused)
wrapped_announce(_sys_idle_elapsed_ticks);
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE,
k_ticks_to_cyc_floor32(1) & 0xFFFF);
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE,
(k_ticks_to_cyc_floor32(1) >> 16) & 0xFFFF);
IRQ_CONNECT(TIMER_0_IRQ, 0, timer_irq_handler, NULL, 0);
irq_enable(TIMER_0_IRQ);
alt_avalon_timer_sc_init((void *)TIMER_0_BASE, 0,
TIMER_0_IRQ, k_ticks_to_cyc_floor32(1));
return 0;
}
uint32_t sys_clock_cycle_get_32(void)
{
/* Per the Altera Embedded IP Peripherals guide, you cannot
@ -85,3 +67,24 @@ uint32_t sys_clock_elapsed(void)
{
return 0;
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE,
k_ticks_to_cyc_floor32(1) & 0xFFFF);
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE,
(k_ticks_to_cyc_floor32(1) >> 16) & 0xFFFF);
IRQ_CONNECT(TIMER_0_IRQ, 0, timer_irq_handler, NULL, 0);
irq_enable(TIMER_0_IRQ);
alt_avalon_timer_sc_init((void *)TIMER_0_BASE, 0,
TIMER_0_IRQ, k_ticks_to_cyc_floor32(1));
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -3,6 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -213,7 +214,7 @@ uint32_t sys_clock_cycle_get_32(void)
#endif
int sys_clock_driver_init(const struct device *dev)
static int sys_clock_driver_init(const struct device *dev)
{
uint32_t val;
@ -240,3 +241,6 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -2,6 +2,7 @@
* Copyright (c) 2021 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -154,7 +155,7 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *
: "a"(*eax), "c"(*ecx));
}
int sys_clock_driver_init(const struct device *dev)
static int sys_clock_driver_init(const struct device *dev)
{
#ifdef CONFIG_ASSERT
uint32_t eax, ebx, ecx, edx;
@ -200,3 +201,6 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -4,7 +4,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -267,50 +267,6 @@ static void timer_int_handler(const void *unused)
}
/**
*
* @brief Initialize and enable the system clock
*
* This routine is used to program the ARCv2 timer to deliver interrupts at the
* rate specified via the CYC_PER_TICK.
*
* @return 0
*/
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
/* ensure that the timer will not generate interrupts */
timer0_control_register_set(0);
#if SMP_TIMER_DRIVER
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
timer_int_handler, NULL, 0);
timer0_limit_register_set(CYC_PER_TICK - 1);
last_time = z_arc_connect_gfrc_read();
start_time = last_time;
#else
last_load = CYC_PER_TICK;
overflow_cycles = 0;
announced_cycles = 0;
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
timer_int_handler, NULL, 0);
timer0_limit_register_set(last_load - 1);
#endif
timer0_count_register_set(0);
timer0_control_register_set(_ARC_V2_TMR_CTRL_NH | _ARC_V2_TMR_CTRL_IE);
/* everything has been configured: safe to enable the interrupt */
irq_enable(IRQ_TIMER0);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
/* If the kernel allows us to miss tick announcements in idle,
@ -459,3 +415,49 @@ void smp_timer_init(void)
irq_enable(IRQ_TIMER0);
}
#endif
/**
*
* @brief Initialize and enable the system clock
*
* This routine is used to program the ARCv2 timer to deliver interrupts at the
* rate specified via the CYC_PER_TICK.
*
* @return 0
*/
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
/* ensure that the timer will not generate interrupts */
timer0_control_register_set(0);
#if SMP_TIMER_DRIVER
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
timer_int_handler, NULL, 0);
timer0_limit_register_set(CYC_PER_TICK - 1);
last_time = z_arc_connect_gfrc_read();
start_time = last_time;
#else
last_load = CYC_PER_TICK;
overflow_cycles = 0;
announced_cycles = 0;
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
timer_int_handler, NULL, 0);
timer0_limit_register_set(last_load - 1);
#endif
timer0_count_register_set(0);
timer0_control_register_set(_ARC_V2_TMR_CTRL_NH | _ARC_V2_TMR_CTRL_IE);
/* everything has been configured: safe to enable the interrupt */
irq_enable(IRQ_TIMER0);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/arm_arch_timer.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
@ -85,21 +85,6 @@ static void arm_arch_timer_compare_isr(const void *arg)
sys_clock_announce(delta_ticks);
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(ARM_ARCH_TIMER_IRQ, ARM_ARCH_TIMER_PRIO,
arm_arch_timer_compare_isr, NULL, ARM_ARCH_TIMER_FLAGS);
arm_arch_timer_init();
arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK);
arm_arch_timer_enable(true);
irq_enable(ARM_ARCH_TIMER_IRQ);
arm_arch_timer_set_irq_mask(false);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
#if defined(CONFIG_TICKLESS_KERNEL)
@ -192,3 +177,21 @@ void smp_timer_init(void)
arm_arch_timer_set_irq_mask(false);
}
#endif
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(ARM_ARCH_TIMER_IRQ, ARM_ARCH_TIMER_PRIO,
arm_arch_timer_compare_isr, NULL, ARM_ARCH_TIMER_FLAGS);
arm_arch_timer_init();
arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK);
arm_arch_timer_enable(true);
irq_enable(ARM_ARCH_TIMER_IRQ);
arm_arch_timer_set_irq_mask(false);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -118,18 +118,6 @@ static void compare_isr(const void *arg)
sys_clock_announce(dticks);
}
/* Runs on core 0 only */
int sys_clock_driver_init(const struct device *dev)
{
uint64_t curr = count();
IRQ_CONNECT(TIMER_IRQ, 0, compare_isr, 0, 0);
set_compare(curr + CYC_PER_TICK);
last_count = curr;
irq_enable(TIMER_IRQ);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -195,3 +183,18 @@ void smp_timer_init(void)
CAVS_INTCTRL[arch_curr_cpu()->id].l2.clear = CAVS_L2_DWCT0;
irq_enable(TIMER_IRQ);
}
/* Runs on core 0 only */
static int sys_clock_driver_init(const struct device *dev)
{
uint64_t curr = count();
IRQ_CONNECT(TIMER_IRQ, 0, compare_isr, 0, 0);
set_compare(curr + CYC_PER_TICK);
last_count = curr;
irq_enable(TIMER_IRQ);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -15,6 +15,7 @@
* the comparator value set is reached.
*/
#include <device.h>
#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/timer/system_timer.h>
@ -183,24 +184,6 @@ static void startDevice(void)
irq_unlock(key);
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
rtc_last = 0U;
initDevice();
startDevice();
/* Enable RTC interrupt. */
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
rtc_isr, 0, 0);
irq_enable(DT_INST_IRQN(0));
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -247,3 +230,24 @@ uint64_t sys_clock_cycle_get_64(void)
{
return AONRTCCurrent64BitValueGet() / RTC_COUNTS_PER_CYCLE;
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
rtc_last = 0U;
initDevice();
startDevice();
/* Enable RTC interrupt. */
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
rtc_isr, 0, 0);
irq_enable(DT_INST_IRQN(0));
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -3,6 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -149,21 +150,6 @@ void sys_clock_isr(void *arg)
z_arm_int_exit();
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET);
last_load = CYC_PER_TICK - 1;
overflow_cyc = 0U;
SysTick->LOAD = last_load;
SysTick->VAL = 0; /* resets timer to last_load */
SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_CLKSOURCE_Msk);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
/* Fast CPUs and a 24 bit counter mean that even idle systems
@ -279,3 +265,21 @@ void sys_clock_disable(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET);
last_load = CYC_PER_TICK - 1;
overflow_cyc = 0U;
SysTick->LOAD = last_load;
SysTick->VAL = 0; /* resets timer to last_load */
SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_CLKSOURCE_Msk);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -67,26 +67,6 @@ static void sys_timer_isr(const void *arg)
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
esp_intr_alloc(DT_IRQN(DT_NODELABEL(systimer0)),
0,
sys_timer_isr,
NULL,
NULL);
systimer_hal_init();
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
systimer_hal_counter_can_stall_by_cpu(SYSTIMER_COUNTER_1, 0, true);
last_count = systimer_alarm();
set_systimer_alarm(last_count + CYC_PER_TICK);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -139,3 +119,26 @@ uint64_t sys_clock_cycle_get_64(void)
{
return systimer_alarm();
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
esp_intr_alloc(DT_IRQN(DT_NODELABEL(systimer0)),
0,
sys_timer_isr,
NULL,
NULL);
systimer_hal_init();
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
systimer_hal_counter_can_stall_by_cpu(SYSTIMER_COUNTER_1, 0, true);
last_count = systimer_alarm();
set_systimer_alarm(last_count + CYC_PER_TICK);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -5,6 +5,7 @@
*/
#define DT_DRV_COMPAT intel_hpet
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -316,56 +317,6 @@ static void config_timer0(unsigned int irq)
hpet_timer_conf_set(val);
}
__boot_func
int sys_clock_driver_init(const struct device *dev)
{
extern int z_clock_hw_cycles_per_sec;
uint32_t hz, reg;
ARG_UNUSED(dev);
ARG_UNUSED(hz);
ARG_UNUSED(z_clock_hw_cycles_per_sec);
DEVICE_MMIO_TOPLEVEL_MAP(hpet_regs, K_MEM_CACHE_NONE);
#if DT_INST_IRQ_HAS_CELL(0, sense)
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
hpet_isr, 0, DT_INST_IRQ(0, sense));
#else
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
hpet_isr, 0, 0);
#endif
config_timer0(DT_INST_IRQN(0));
irq_enable(DT_INST_IRQN(0));
#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME
hz = (uint32_t)(HPET_COUNTER_CLK_PERIOD / hpet_counter_clk_period_get());
z_clock_hw_cycles_per_sec = hz;
cyc_per_tick = hz / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
#endif
/* Note: we set the legacy routing bit, because otherwise
* nothing in Zephyr disables the PIT which then fires
* interrupts into the same IRQ. But that means we're then
* forced to use IRQ2 contra the way the kconfig IRQ selection
* is supposed to work. Should fix this.
*/
reg = hpet_gconf_get();
reg |= GCONF_LR | GCONF_ENABLE;
hpet_gconf_set(reg);
last_count = hpet_counter_get();
if (cyc_per_tick >= HPET_CMP_MIN_DELAY) {
hpet_timer_comparator_set(last_count + cyc_per_tick);
} else {
hpet_timer_comparator_set(last_count + HPET_CMP_MIN_DELAY);
}
return 0;
}
__boot_func
void smp_timer_init(void)
{
@ -453,3 +404,56 @@ void sys_clock_idle_exit(void)
reg |= GCONF_ENABLE;
hpet_gconf_set(reg);
}
__boot_func
static int sys_clock_driver_init(const struct device *dev)
{
extern int z_clock_hw_cycles_per_sec;
uint32_t hz, reg;
ARG_UNUSED(dev);
ARG_UNUSED(hz);
ARG_UNUSED(z_clock_hw_cycles_per_sec);
DEVICE_MMIO_TOPLEVEL_MAP(hpet_regs, K_MEM_CACHE_NONE);
#if DT_INST_IRQ_HAS_CELL(0, sense)
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
hpet_isr, 0, DT_INST_IRQ(0, sense));
#else
IRQ_CONNECT(DT_INST_IRQN(0),
DT_INST_IRQ(0, priority),
hpet_isr, 0, 0);
#endif
config_timer0(DT_INST_IRQN(0));
irq_enable(DT_INST_IRQN(0));
#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME
hz = (uint32_t)(HPET_COUNTER_CLK_PERIOD / hpet_counter_clk_period_get());
z_clock_hw_cycles_per_sec = hz;
cyc_per_tick = hz / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
#endif
/* Note: we set the legacy routing bit, because otherwise
* nothing in Zephyr disables the PIT which then fires
* interrupts into the same IRQ. But that means we're then
* forced to use IRQ2 contra the way the kconfig IRQ selection
* is supposed to work. Should fix this.
*/
reg = hpet_gconf_get();
reg |= GCONF_LR | GCONF_ENABLE;
hpet_gconf_set(reg);
last_count = hpet_counter_get();
if (cyc_per_tick >= HPET_CMP_MIN_DELAY) {
hpet_timer_comparator_set(last_count + cyc_per_tick);
} else {
hpet_timer_comparator_set(last_count + HPET_CMP_MIN_DELAY);
}
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -5,6 +5,7 @@
#define DT_DRV_COMPAT ite_it8xxx2_timer
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <dt-bindings/interrupt-controller/ite-intc.h>
#include <soc.h>
@ -331,7 +332,7 @@ static int timer_init(enum ext_timer_idx ext_timer,
return 0;
}
int sys_clock_driver_init(const struct device *dev)
static int sys_clock_driver_init(const struct device *dev)
{
int ret;
@ -372,3 +373,6 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -12,6 +12,7 @@
#define DT_DRV_COMPAT gaisler_gptimer
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
@ -101,7 +102,7 @@ static void init_downcounter(volatile struct gptimer_timer_regs *tmr)
tmr->ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_RS | GPTIMER_CTRL_EN;
}
int sys_clock_driver_init(const struct device *dev)
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
const int timer_interrupt = get_timer_irq();
@ -127,3 +128,6 @@ int sys_clock_driver_init(const struct device *dev)
irq_enable(timer_interrupt);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -72,7 +72,7 @@ uint32_t sys_clock_elapsed(void)
return 0;
}
int sys_clock_driver_init(const struct device *dev)
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(TIMER_IRQ, DT_INST_IRQ(0, priority),
@ -94,3 +94,6 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -6,6 +6,7 @@
#define DT_DRV_COMPAT microchip_xec_rtos_timer
#include <device.h>
#include <devicetree.h>
#include <soc.h>
#include <drivers/timer/system_timer.h>
@ -366,7 +367,37 @@ void sys_clock_disable(void)
TIMER_REGS->CTRL = 0U;
}
int sys_clock_driver_init(const struct device *dev)
#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT
/*
* We implement custom busy wait using a MEC1501 basic timer running on
* the 48MHz clock domain. This code is here for future power management
* save/restore of the timer context.
*/
/*
* 32-bit basic timer 0 configured for 1MHz count up, auto-reload,
* and no interrupt generation.
*/
void arch_busy_wait(uint32_t usec_to_wait)
{
if (usec_to_wait == 0) {
return;
}
uint32_t start = BTMR32_0_REGS->CNT;
for (;;) {
uint32_t curr = BTMR32_0_REGS->CNT;
if ((curr - start) >= usec_to_wait) {
break;
}
}
}
#endif
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
@ -413,32 +444,5 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT
/*
* We implement custom busy wait using a MEC1501 basic timer running on
* the 48MHz clock domain. This code is here for future power management
* save/restore of the timer context.
*/
/*
* 32-bit basic timer 0 configured for 1MHz count up, auto-reload,
* and no interrupt generation.
*/
void arch_busy_wait(uint32_t usec_to_wait)
{
if (usec_to_wait == 0) {
return;
}
uint32_t start = BTMR32_0_REGS->CNT;
for (;;) {
uint32_t curr = BTMR32_0_REGS->CNT;
if ((curr - start) >= usec_to_wait) {
break;
}
}
}
#endif
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -6,6 +6,7 @@
#define DT_DRV_COMPAT nxp_kinetis_lptmr
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <fsl_lptmr.h>
@ -91,7 +92,7 @@ static void mcux_lptmr_timer_isr(void *arg)
LPTMR_ClearStatusFlags(LPTMR_BASE, kLPTMR_TimerCompareFlag);
}
int sys_clock_driver_init(const struct device *dev)
static int sys_clock_driver_init(const struct device *dev)
{
lptmr_config_t config;
@ -120,3 +121,6 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -6,6 +6,7 @@
#define DT_DRV_COMPAT nxp_os_timer
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -50,30 +51,6 @@ void mcux_lpc_ostick_isr(void *arg)
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
}
int sys_clock_driver_init(const struct device *device)
{
ARG_UNUSED(device);
/* Configure event timer's ISR */
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
mcux_lpc_ostick_isr, NULL, 0);
base = (OSTIMER_Type *)DT_INST_REG_ADDR(0);
EnableDeepSleepIRQ(DT_INST_IRQN(0));
/* Initialize the OS timer, setting clock configuration. */
OSTIMER_Init(base);
last_count = OSTIMER_GetCurrentTimerValue(base);
OSTIMER_SetMatchValue(base, last_count + CYC_PER_TICK, NULL);
/* Enable event timer interrupt */
irq_enable(DT_INST_IRQN(0));
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -132,3 +109,30 @@ uint64_t sys_clock_cycle_get_64(void)
{
return OSTIMER_GetCurrentTimerValue(base);
}
static int sys_clock_driver_init(const struct device *device)
{
ARG_UNUSED(device);
/* Configure event timer's ISR */
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
mcux_lpc_ostick_isr, NULL, 0);
base = (OSTIMER_Type *)DT_INST_REG_ADDR(0);
EnableDeepSleepIRQ(DT_INST_IRQN(0));
/* Initialize the OS timer, setting clock configuration. */
OSTIMER_Init(base);
last_count = OSTIMER_GetCurrentTimerValue(base);
OSTIMER_SetMatchValue(base, last_count + CYC_PER_TICK, NULL);
/* Enable event timer interrupt */
irq_enable(DT_INST_IRQN(0));
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -60,26 +60,6 @@ void np_timer_isr_test_hook(const void *arg)
np_timer_isr(NULL);
}
/*
* @brief Initialize system timer driver
*
* Enable the hw timer, setting its tick period, and setup its interrupt
*/
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
tick_period = 1000000ul / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
last_tick_time = hwm_get_time();
hwtimer_enable(tick_period);
IRQ_CONNECT(TIMER_TICK_IRQ, 1, np_timer_isr, 0, 0);
irq_enable(TIMER_TICK_IRQ);
return 0;
}
/**
* @brief Set system clock timeout
*
@ -143,3 +123,26 @@ void sys_clock_disable(void)
hwtimer_set_silent_ticks(INT64_MAX);
}
#endif /* CONFIG_SYSTEM_CLOCK_DISABLE */
/*
* @brief Initialize system timer driver
*
* Enable the hw timer, setting its tick period, and setup its interrupt
*/
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
tick_period = 1000000ul / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
last_tick_time = hwm_get_time();
hwtimer_enable(tick_period);
IRQ_CONNECT(TIMER_TICK_IRQ, 1, np_timer_isr, 0, 0);
irq_enable(TIMER_TICK_IRQ);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -34,6 +34,7 @@
* "sleep/deep sleep" power state if CONFIG_PM is enabled.
*/
#include <device.h>
#include <drivers/clock_control.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>
@ -311,46 +312,6 @@ void z_nrf_rtc_timer_chan_free(int32_t chan)
atomic_or(&alloc_mask, BIT(chan));
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
static const enum nrf_lfclk_start_mode mode =
IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) ?
CLOCK_CONTROL_NRF_LF_START_NOWAIT :
(IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) ?
CLOCK_CONTROL_NRF_LF_START_AVAILABLE :
CLOCK_CONTROL_NRF_LF_START_STABLE);
/* TODO: replace with counter driver to access RTC */
nrf_rtc_prescaler_set(RTC, 0);
for (int32_t chan = 0; chan < CHAN_COUNT; chan++) {
nrf_rtc_int_enable(RTC, RTC_CHANNEL_INT_MASK(chan));
}
NVIC_ClearPendingIRQ(RTC_IRQn);
IRQ_CONNECT(RTC_IRQn, DT_IRQ(DT_NODELABEL(RTC_LABEL), priority),
rtc_nrf_isr, 0, 0);
irq_enable(RTC_IRQn);
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR);
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START);
int_mask = BIT_MASK(CHAN_COUNT);
if (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT) {
alloc_mask = BIT_MASK(EXT_CHAN_COUNT) << 1;
}
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
compare_set(0, counter() + CYC_PER_TICK,
sys_clock_timeout_handler, NULL);
}
z_nrf_clock_control_lf_on(mode);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -409,3 +370,46 @@ uint32_t sys_clock_cycle_get_32(void)
k_spin_unlock(&lock, key);
return ret;
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
static const enum nrf_lfclk_start_mode mode =
IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) ?
CLOCK_CONTROL_NRF_LF_START_NOWAIT :
(IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) ?
CLOCK_CONTROL_NRF_LF_START_AVAILABLE :
CLOCK_CONTROL_NRF_LF_START_STABLE);
/* TODO: replace with counter driver to access RTC */
nrf_rtc_prescaler_set(RTC, 0);
for (int32_t chan = 0; chan < CHAN_COUNT; chan++) {
nrf_rtc_int_enable(RTC, RTC_CHANNEL_INT_MASK(chan));
}
NVIC_ClearPendingIRQ(RTC_IRQn);
IRQ_CONNECT(RTC_IRQn, DT_IRQ(DT_NODELABEL(RTC_LABEL), priority),
rtc_nrf_isr, 0, 0);
irq_enable(RTC_IRQn);
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR);
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START);
int_mask = BIT_MASK(CHAN_COUNT);
if (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT) {
alloc_mask = BIT_MASK(EXT_CHAN_COUNT) << 1;
}
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
compare_set(0, counter() + CYC_PER_TICK,
sys_clock_timeout_handler, NULL);
}
z_nrf_clock_control_lf_on(mode);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <soc.h>
#include <drivers/timer/system_timer.h>
#include <drivers/clock_control.h>
@ -66,13 +67,24 @@ static void cmt_isr(void *arg)
sys_clock_announce(1);
}
uint32_t sys_clock_elapsed(void)
{
/* Always return 0 for tickful operation */
return 0;
}
uint32_t sys_clock_cycle_get_32(void)
{
return sys_read32(TIMER_BASE_ADDR + CMCNT1_OFFSET);
}
/*
* Initialize both channels at same frequency,
* Set the first one to generates interrupt at CYCLES_PER_TICK.
* The second one is used for cycles count, the match value is set
* at max uint32_t.
*/
int sys_clock_driver_init(const struct device *device)
static int sys_clock_driver_init(const struct device *device)
{
const struct device *clk;
uint32_t reg_val;
@ -140,13 +152,5 @@ int sys_clock_driver_init(const struct device *device)
return 0;
}
uint32_t sys_clock_elapsed(void)
{
/* Always return 0 for tickful operation */
return 0;
}
uint32_t sys_clock_cycle_get_32(void)
{
return sys_read32(TIMER_BASE_ADDR + CMCNT1_OFFSET);
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -3,6 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -79,17 +80,6 @@ static void timer_isr(const void *arg)
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(RISCV_MACHINE_TIMER_IRQ, 0, timer_isr, NULL, 0);
last_count = mtime();
set_mtimecmp(last_count + CYC_PER_TICK);
irq_enable(RISCV_MACHINE_TIMER_IRQ);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -152,3 +142,17 @@ uint64_t sys_clock_cycle_get_64(void)
{
return mtime();
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(RISCV_MACHINE_TIMER_IRQ, 0, timer_isr, NULL, 0);
last_count = mtime();
set_mtimecmp(last_count + CYC_PER_TICK);
irq_enable(RISCV_MACHINE_TIMER_IRQ);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -6,6 +6,7 @@
#define DT_DRV_COMPAT openisa_rv32m1_lptmr
#include <device.h>
#include <zephyr.h>
#include <sys/util.h>
#include <drivers/timer/system_timer.h>
@ -53,7 +54,20 @@ static void lptmr_irq_handler(const struct device *unused)
sys_clock_announce(1); /* Poke the scheduler. */
}
int sys_clock_driver_init(const struct device *unused)
uint32_t sys_clock_cycle_get_32(void)
{
return cycle_count + SYSTEM_TIMER_INSTANCE->CNR;
}
/*
* Since we're not tickless, this is identically zero.
*/
uint32_t sys_clock_elapsed(void)
{
return 0;
}
static int sys_clock_driver_init(const struct device *unused)
{
uint32_t csr, psr, sircdiv; /* LPTMR registers */
@ -131,15 +145,5 @@ int sys_clock_driver_init(const struct device *unused)
return 0;
}
uint32_t sys_clock_cycle_get_32(void)
{
return cycle_count + SYSTEM_TIMER_INSTANCE->CNR;
}
/*
* Since we're not tickless, this is identically zero.
*/
uint32_t sys_clock_elapsed(void)
{
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -16,6 +16,7 @@
* generate an interrupt every tick.
*/
#include <device.h>
#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/timer/system_timer.h>
@ -175,7 +176,71 @@ static void rtc_isr(const void *arg)
#endif /* CONFIG_TICKLESS_KERNEL */
}
int sys_clock_driver_init(const struct device *dev)
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
#ifdef CONFIG_TICKLESS_KERNEL
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
ticks = CLAMP(ticks - 1, 0, (int32_t) MAX_TICKS);
/* Compute number of RTC cycles until the next timeout. */
uint32_t count = rtc_count();
uint32_t timeout = ticks * CYCLES_PER_TICK + count % CYCLES_PER_TICK;
/* Round to the nearest tick boundary. */
timeout = (timeout + CYCLES_PER_TICK - 1) / CYCLES_PER_TICK
* CYCLES_PER_TICK;
if (timeout < TICK_THRESHOLD) {
timeout += CYCLES_PER_TICK;
}
rtc_sync();
RTC0->COMP[0].reg = count + timeout;
#else /* !CONFIG_TICKLESS_KERNEL */
if (ticks == K_TICKS_FOREVER) {
/* Disable comparator for K_TICKS_FOREVER and other negative
* values.
*/
rtc_timeout = rtc_counter;
return;
}
if (ticks < 1) {
ticks = 1;
}
/* Avoid race condition between reading counter and ISR incrementing
* it.
*/
int key = irq_lock();
rtc_timeout = rtc_counter + ticks;
irq_unlock(key);
#endif /* CONFIG_TICKLESS_KERNEL */
}
uint32_t sys_clock_elapsed(void)
{
#ifdef CONFIG_TICKLESS_KERNEL
return (rtc_count() - rtc_last) / CYCLES_PER_TICK;
#else
return rtc_counter - rtc_last;
#endif
}
uint32_t sys_clock_cycle_get_32(void)
{
/* Just return the absolute value of RTC cycle counter. */
return rtc_count();
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
@ -252,66 +317,5 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
#ifdef CONFIG_TICKLESS_KERNEL
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
ticks = CLAMP(ticks - 1, 0, (int32_t) MAX_TICKS);
/* Compute number of RTC cycles until the next timeout. */
uint32_t count = rtc_count();
uint32_t timeout = ticks * CYCLES_PER_TICK + count % CYCLES_PER_TICK;
/* Round to the nearest tick boundary. */
timeout = (timeout + CYCLES_PER_TICK - 1) / CYCLES_PER_TICK
* CYCLES_PER_TICK;
if (timeout < TICK_THRESHOLD) {
timeout += CYCLES_PER_TICK;
}
rtc_sync();
RTC0->COMP[0].reg = count + timeout;
#else /* !CONFIG_TICKLESS_KERNEL */
if (ticks == K_TICKS_FOREVER) {
/* Disable comparator for K_TICKS_FOREVER and other negative
* values.
*/
rtc_timeout = rtc_counter;
return;
}
if (ticks < 1) {
ticks = 1;
}
/* Avoid race condition between reading counter and ISR incrementing
* it.
*/
int key = irq_lock();
rtc_timeout = rtc_counter + ticks;
irq_unlock(key);
#endif /* CONFIG_TICKLESS_KERNEL */
}
uint32_t sys_clock_elapsed(void)
{
#ifdef CONFIG_TICKLESS_KERNEL
return (rtc_count() - rtc_last) / CYCLES_PER_TICK;
#else
return rtc_counter - rtc_last;
#endif
}
uint32_t sys_clock_cycle_get_32(void)
{
/* Just return the absolute value of RTC cycle counter. */
return rtc_count();
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

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);

View file

@ -23,13 +23,6 @@ void __weak sys_clock_isr(void *arg)
__ASSERT_NO_MSG(false);
}
int __weak sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
return 0;
}
void __weak sys_clock_set_timeout(int32_t ticks, bool idle)
{
}
@ -41,6 +34,3 @@ void __weak sys_clock_idle_exit(void)
void __weak sys_clock_disable(void)
{
}
SYS_DEVICE_DEFINE("sys_clock", sys_clock_driver_init,
PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -7,6 +7,7 @@
#define DT_DRV_COMPAT xlnx_ttcps
#include <device.h>
#include <soc.h>
#include <drivers/timer/system_timer.h>
#include "xlnx_psttc_timer_priv.h"
@ -96,7 +97,50 @@ static void ttc_isr(const void *arg)
sys_clock_announce(ticks);
}
int sys_clock_driver_init(const struct device *dev)
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
#ifdef CONFIG_TICKLESS_KERNEL
uint32_t cycles;
uint32_t next_cycles;
/* Read counter value */
cycles = read_count();
/* Calculate timeout counter value */
if (ticks == K_TICKS_FOREVER) {
next_cycles = cycles + CYCLES_NEXT_MAX;
} else {
next_cycles = cycles + ((uint32_t)ticks * CYCLES_PER_TICK);
}
/* Set match value for the next interrupt */
update_match(cycles, next_cycles);
#endif
}
uint32_t sys_clock_elapsed(void)
{
#ifdef CONFIG_TICKLESS_KERNEL
uint32_t cycles;
/* Read counter value */
cycles = read_count();
/* Return the number of ticks since last announcement */
return (cycles - last_cycles) / CYCLES_PER_TICK;
#else
/* Always return 0 for tickful operation */
return 0;
#endif
}
uint32_t sys_clock_cycle_get_32(void)
{
/* Return the current counter value */
return read_count();
}
static int sys_clock_driver_init(const struct device *dev)
{
uint32_t reg_val;
ARG_UNUSED(dev);
@ -153,45 +197,5 @@ int sys_clock_driver_init(const struct device *dev)
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
#ifdef CONFIG_TICKLESS_KERNEL
uint32_t cycles;
uint32_t next_cycles;
/* Read counter value */
cycles = read_count();
/* Calculate timeout counter value */
if (ticks == K_TICKS_FOREVER) {
next_cycles = cycles + CYCLES_NEXT_MAX;
} else {
next_cycles = cycles + ((uint32_t)ticks * CYCLES_PER_TICK);
}
/* Set match value for the next interrupt */
update_match(cycles, next_cycles);
#endif
}
uint32_t sys_clock_elapsed(void)
{
#ifdef CONFIG_TICKLESS_KERNEL
uint32_t cycles;
/* Read counter value */
cycles = read_count();
/* Return the number of ticks since last announcement */
return (cycles - last_cycles) / CYCLES_PER_TICK;
#else
/* Always return 0 for tickful operation */
return 0;
#endif
}
uint32_t sys_clock_cycle_get_32(void)
{
/* Return the current counter value */
return read_count();
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -3,6 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <drivers/timer/system_timer.h>
#include <sys_clock.h>
#include <spinlock.h>
@ -56,16 +57,6 @@ static void ccompare_isr(const void *arg)
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(TIMER_IRQ, 0, ccompare_isr, 0, 0);
set_ccompare(ccount() + CYC_PER_TICK);
irq_enable(TIMER_IRQ);
return 0;
}
void sys_clock_set_timeout(int32_t ticks, bool idle)
{
ARG_UNUSED(idle);
@ -122,3 +113,16 @@ void smp_timer_init(void)
irq_enable(TIMER_IRQ);
}
#endif
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
IRQ_CONNECT(TIMER_IRQ, 0, ccompare_isr, 0, 0);
set_ccompare(ccount() + CYC_PER_TICK);
irq_enable(TIMER_IRQ);
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

View file

@ -16,8 +16,7 @@
#define ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_
#include <stdbool.h>
#include <device.h>
#include <stdbool.h>
#include <zephyr/types.h>
#ifdef __cplusplus
extern "C" {
@ -29,15 +28,6 @@ extern "C" {
* @{
*/
/**
* @brief Initialize system clock driver
*
* The system clock is a Zephyr device created globally. This is its
* initialization callback. It is a weak symbol that will be
* implemented as a noop if undefined in the clock driver.
*/
extern int sys_clock_driver_init(const struct device *dev);
/**
* @brief Set system clock timeout
*