From ae995123055e1da6f7be3f0af2eb576a6d6a0f2e Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Mon, 21 Oct 2024 13:26:39 +0300 Subject: [PATCH 01/10] drivers: timer: Add RTC timer driver for cc23x0 Add support for RTC as timer for cc23x0 SoC. Signed-off-by: Stoyan Bogdanov --- drivers/timer/CMakeLists.txt | 1 + drivers/timer/Kconfig.cc23x0_rtc | 12 +++ drivers/timer/cc23x0_rtc_timer.c | 122 +++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 drivers/timer/Kconfig.cc23x0_rtc create mode 100644 drivers/timer/cc23x0_rtc_timer.c diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index 3c488da9a3e72..408873f777423 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_ARM_ARCH_TIMER arm_arch_timer.c) zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_TIMER intel_adsp_timer.c) zephyr_library_sources_ifdef(CONFIG_CC13XX_CC26XX_RTC_TIMER cc13xx_cc26xx_rtc_timer.c) zephyr_library_sources_ifdef(CONFIG_CC23X0_SYSTIM_TIMER cc23x0_systim_timer.c) +zephyr_library_sources_ifdef(CONFIG_CC23X0_RTC_TIMER cc23x0_rtc_timer.c) zephyr_library_sources_ifdef(CONFIG_CH32V00X_SYSTICK wch_systick_ch32v00x.c) zephyr_library_sources_ifdef(CONFIG_CORTEX_M_SYSTICK cortex_m_systick.c) zephyr_library_sources_ifdef(CONFIG_ESP32_SYS_TIMER esp32_sys_timer.c) diff --git a/drivers/timer/Kconfig.cc23x0_rtc b/drivers/timer/Kconfig.cc23x0_rtc new file mode 100644 index 0000000000000..74c4fc177204a --- /dev/null +++ b/drivers/timer/Kconfig.cc23x0_rtc @@ -0,0 +1,12 @@ +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config CC23X0_RTC_TIMER + bool "TI SimpleLink CC23X0 RTC system clock timer" + default y + depends on HAS_CC23X0_SDK + select TICKLESS_CAPABLE + help + This module provides the RTC as "system clock driver" interfaces + for the TI Simplelink CC23X0 devices. diff --git a/drivers/timer/cc23x0_rtc_timer.c b/drivers/timer/cc23x0_rtc_timer.c new file mode 100644 index 0000000000000..171ec1436c446 --- /dev/null +++ b/drivers/timer/cc23x0_rtc_timer.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_rtc_timer + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define RTC_TIMEOUT_MAX 0xFFBFFFFFU + +/* Set rtc interrupt to lowest priority */ +#define SYSTIM_ISR_PRIORITY 3U + +/* Keep track of rtc counter at previous announcement to the kernel */ +static uint32_t last_rtc_count; + +static void rtc_isr(const void *arg); +static int sys_clock_driver_init(void); + +#define TICK_PERIOD_MICRO_SEC (1000000 / CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + ARG_UNUSED(idle); + + /* If timeout is necessary */ + if (ticks != K_TICKS_FOREVER) { + /* Get current value as early as possible */ + uint32_t ticks_now = HWREG(RTC_BASE + RTC_O_TIME8U); + + if ((ticks_now + ticks) >= RTC_TIMEOUT_MAX) { + /* Reset timer and start from 0 */ + HWREG(RTC_BASE + RTC_O_CTL) = 0x1; + HWREG(RTC_BASE + RTC_O_CH0CC8U) = ticks; + } + + HWREG(RTC_BASE + RTC_O_CH0CC8U) = ticks_now + ticks; + } +} + +uint32_t sys_clock_elapsed(void) +{ + uint32_t current_rtc_count = HWREG(RTC_BASE + RTC_O_TIME8U); + + uint32_t elapsed_rtc; + + if (current_rtc_count >= last_rtc_count) { + elapsed_rtc = current_rtc_count - last_rtc_count; + } else { + elapsed_rtc = (0xFFFFFFFF - last_rtc_count) + current_rtc_count; + } + + int32_t elapsed_ticks = elapsed_rtc / TICK_PERIOD_MICRO_SEC; + + return elapsed_ticks; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + return HWREG(RTC_BASE + RTC_O_TIME8U); +} + +void rtc_isr(const void *arg) +{ + uint32_t current_rtc_count = HWREG(RTC_BASE + RTC_O_TIME8U); + + uint32_t elapsed_rtc; + + if (current_rtc_count >= last_rtc_count) { + elapsed_rtc = current_rtc_count - last_rtc_count; + } else { + elapsed_rtc = (0xFFFFFFFF - last_rtc_count) + current_rtc_count; + } + + int32_t elapsed_ticks = elapsed_rtc; + + HWREG(RTC_BASE + RTC_O_ICLR) = 0x1; + + sys_clock_announce(elapsed_ticks); + + last_rtc_count = current_rtc_count; +} + +static int sys_clock_driver_init(void) +{ + uint32_t now_ticks; + + now_ticks = HWREG(RTC_BASE + RTC_O_TIME8U); + last_rtc_count = now_ticks; + + HWREG(RTC_BASE + RTC_O_ICLR) = 0x3; + HWREG(RTC_BASE + RTC_O_IMCLR) = 0x3; + + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = EVTSVT_CPUIRQ16SEL_PUBID_AON_RTC_COMB; + HWREG(RTC_BASE + RTC_O_CH0CC8U) = now_ticks + RTC_TIMEOUT_MAX; + + HWREG(RTC_BASE + RTC_O_IMASK) = 0x1; + HWREG(RTC_BASE + RTC_O_ARMSET) = 0x1; + + /* Take configurable interrupt IRQ16 for rtc */ + IRQ_CONNECT(CPUIRQ16_IRQn, SYSTIM_ISR_PRIORITY, rtc_isr, 0, 0); + irq_enable(CPUIRQ16_IRQn); + + return 0; +} + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); From 46d3ec66569ff3d2a7c9c4e482a883ec6f2c0e8f Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Mon, 21 Oct 2024 13:59:37 +0300 Subject: [PATCH 02/10] drivers: timer: cc23x0: Add option to select between RTC and SYSTIM Add choice menu where could be selected between RTC or SYSTIM for system timer. Signed-off-by: Stoyan Bogdanov --- drivers/timer/Kconfig | 2 +- drivers/timer/Kconfig.cc23x0 | 26 ++++++++++++++++++++++++++ drivers/timer/Kconfig.cc23x0_systim | 13 ------------- 3 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 drivers/timer/Kconfig.cc23x0 delete mode 100644 drivers/timer/Kconfig.cc23x0_systim diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index c154370c45630..5038252e851fe 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -69,7 +69,7 @@ source "drivers/timer/Kconfig.arcv2" source "drivers/timer/Kconfig.arm_arch" source "drivers/timer/Kconfig.cavs" source "drivers/timer/Kconfig.cc13xx_cc26xx_rtc" -source "drivers/timer/Kconfig.cc23x0_systim" +source "drivers/timer/Kconfig.cc23x0" source "drivers/timer/Kconfig.wch_ch32v00x" source "drivers/timer/Kconfig.cortex_m_systick" source "drivers/timer/Kconfig.esp32" diff --git a/drivers/timer/Kconfig.cc23x0 b/drivers/timer/Kconfig.cc23x0 new file mode 100644 index 0000000000000..95a0453fa315c --- /dev/null +++ b/drivers/timer/Kconfig.cc23x0 @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "TI SimpleLink CC23X default System Timer" + depends on HAS_CC23X0_SDK + default CC23X0_RTC_TIMER + help + Select Default System Timer. + +config CC23X0_SYSTIM_TIMER + bool "SYSTIM timer" + select TICKLESS_CAPABLE + help + This module provides SYSTIM as "system clock driver" interfaces + for the TI Simplelink CC23X0 devices. + +config CC23X0_RTC_TIMER + bool "RTC timer" + select TICKLESS_CAPABLE + help + This module provides RTC as "system clock driver" interfaces + for the TI Simplelink CC23X0 devices. +endchoice diff --git a/drivers/timer/Kconfig.cc23x0_systim b/drivers/timer/Kconfig.cc23x0_systim deleted file mode 100644 index 41db73e6d52c6..0000000000000 --- a/drivers/timer/Kconfig.cc23x0_systim +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2024 Texas Instruments Incorporated -# Copyright (c) 2024 BayLibre, SAS -# -# SPDX-License-Identifier: Apache-2.0 - -config CC23X0_SYSTIM_TIMER - bool "TI SimpleLink CC23X0 system clock timer" - default y - depends on HAS_CC23X0_SDK - select TICKLESS_CAPABLE - help - This module provides the "system clock driver" interfaces - for the TI Simplelink CC23X0 devices. From 2e77346ebc357ef4a6688435d835466757092962 Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Mon, 21 Oct 2024 14:01:45 +0300 Subject: [PATCH 03/10] drivers: counter: cc23x0: Add dependency for RTC In case RTC is used for system timer, it should not be used as counter device. Dependency restricts counter driver to work only with SYSTIM. Signed-off-by: Stoyan Bogdanov --- drivers/counter/Kconfig.cc23x0_rtc | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/counter/Kconfig.cc23x0_rtc b/drivers/counter/Kconfig.cc23x0_rtc index 5afcbda2d3e85..ce4e9ad6b2c19 100644 --- a/drivers/counter/Kconfig.cc23x0_rtc +++ b/drivers/counter/Kconfig.cc23x0_rtc @@ -5,5 +5,6 @@ config COUNTER_CC23X0_RTC bool "CC23x0 Counter driver based on the RTC Timer" default y depends on DT_HAS_TI_CC23X0_RTC_ENABLED + depends on CC23X0_SYSTIM_TIMER help Enable counter driver based on RTC timer for cc23x0 From d0cbfafd208db4f463d6aa70420f40ad0679e0b8 Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Mon, 21 Oct 2024 14:02:49 +0300 Subject: [PATCH 04/10] soc: ti: cc23x0: Add clock definition for RTC Add conditonal definition for RTC and SYSTIM with different values for both of them respecting clock speed and ticks per minute. Signed-off-by: Stoyan Bogdanov --- soc/ti/simplelink/cc23x0/Kconfig.defconfig | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/soc/ti/simplelink/cc23x0/Kconfig.defconfig b/soc/ti/simplelink/cc23x0/Kconfig.defconfig index 442c9b09c9e07..8341ef56e96b3 100644 --- a/soc/ti/simplelink/cc23x0/Kconfig.defconfig +++ b/soc/ti/simplelink/cc23x0/Kconfig.defconfig @@ -10,8 +10,20 @@ if SOC_SERIES_CC23X0 config SYS_CLOCK_HW_CYCLES_PER_SEC default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) -config SYS_CLOCK_TICKS_PER_SEC - default 1000 +if CC23X0_RTC_TIMER + config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + + config SYS_CLOCK_TICKS_PER_SEC + default 125375 +endif +if CC23X0_SYSTIM_TIMER + config SYS_CLOCK_HW_CYCLES_PER_SEC + default 48000000 + + config SYS_CLOCK_TICKS_PER_SEC + default 1000 +endif config NUM_IRQS default 19 From 922498a427b9f07b8560582944ecd27457890662 Mon Sep 17 00:00:00 2001 From: Julien Panis Date: Thu, 17 Oct 2024 16:55:18 +0200 Subject: [PATCH 05/10] dts: bindings: clock: Add TI cc23x0 external low-frequency oscillator External 32.768 kHz crystal oscillator (LFXT) connected across the X32P input and X32N output pins. Signed-off-by: Julien Panis --- dts/bindings/clock/ti,cc23x0-lf-xosc.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 dts/bindings/clock/ti,cc23x0-lf-xosc.yaml diff --git a/dts/bindings/clock/ti,cc23x0-lf-xosc.yaml b/dts/bindings/clock/ti,cc23x0-lf-xosc.yaml new file mode 100644 index 0000000000000..4ba43598b299c --- /dev/null +++ b/dts/bindings/clock/ti,cc23x0-lf-xosc.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Baylibre, SAS +# SPDX-License-Identifier: Apache-2.0 + +description: TI CC23X0 external low-frequency oscillator + +compatible: "ti,cc23x0-lf-xosc" + +include: base.yaml From 00a7ca3627d2669c637d49ac96384a255c333e87 Mon Sep 17 00:00:00 2001 From: Julien Panis Date: Thu, 17 Oct 2024 16:57:55 +0200 Subject: [PATCH 06/10] boards: ti: lp_em_cc2340r5: Add external low-frequency oscillator Enable external 32 kHz crystal oscillator. Signed-off-by: Julien Panis --- boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts index 1a2f8be10d849..34f0fe9316e7b 100644 --- a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts @@ -62,6 +62,10 @@ zephyr,code = ; }; }; + + lfxosc: lf_xosc { + compatible = "ti,cc23x0-lf-xosc"; + }; }; &gpio0 { From ed7b8709d3a48b80a03f4b9d8ae19be70e6080a9 Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Fri, 4 Oct 2024 13:26:15 +0300 Subject: [PATCH 07/10] soc: ti: cc23x0: Add power management Add power management capabilities for cc23x0: - runtime-idle - standby - soft-off Signed-off-by: Stoyan Bogdanov --- soc/ti/simplelink/cc23x0/CMakeLists.txt | 2 + soc/ti/simplelink/cc23x0/Kconfig | 2 + soc/ti/simplelink/cc23x0/power.c | 200 ++++++++++++++++++++++++ soc/ti/simplelink/cc23x0/soc.c | 3 + 4 files changed, 207 insertions(+) create mode 100644 soc/ti/simplelink/cc23x0/power.c diff --git a/soc/ti/simplelink/cc23x0/CMakeLists.txt b/soc/ti/simplelink/cc23x0/CMakeLists.txt index b8e02adbd58e8..27581e425aea6 100644 --- a/soc/ti/simplelink/cc23x0/CMakeLists.txt +++ b/soc/ti/simplelink/cc23x0/CMakeLists.txt @@ -7,6 +7,8 @@ zephyr_sources(soc.c) zephyr_sources(ccfg.c) zephyr_include_directories(.) +zephyr_sources_ifdef(CONFIG_PM power.c) + zephyr_linker_sources_ifdef(CONFIG_HAS_TI_CCFG SECTIONS ccfg.ld) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/ti/simplelink/cc23x0/Kconfig b/soc/ti/simplelink/cc23x0/Kconfig index fa1c2c45af3e3..7580070e3df7a 100644 --- a/soc/ti/simplelink/cc23x0/Kconfig +++ b/soc/ti/simplelink/cc23x0/Kconfig @@ -19,6 +19,8 @@ config SOC_SERIES_CC23X0 select THREAD_STACK_INFO select BUILD_OUTPUT_HEX select BUILD_NO_GAP_FILL + select HAS_PM + select PM_DEVICE if PM menu "Bootloader Configuration" depends on SOC_SERIES_CC23X0 diff --git a/soc/ti/simplelink/cc23x0/power.c b/soc/ti/simplelink/cc23x0/power.c new file mode 100644 index 0000000000000..54512c9cf23ba --- /dev/null +++ b/soc/ti/simplelink/cc23x0/power.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 Baylibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Configuring TI Power module to not use its policy function (we use Zephyr's + * instead), and disable oscillator calibration functionality for now. + */ +const PowerCC23X0_Config PowerCC23X0_config = { + .policyInitFxn = NULL, + .policyFxn = NULL, +}; + +#ifdef CONFIG_PM + +#define MAX_SYSTIMER_DELTA 0xFFBFFFFFU +#define RTC_TO_SYSTIM_TICKS 8U +#define SYSTIM_CH_STEP 4U +#define SYSTIM_CH(idx) (SYSTIM_O_CH0CC + idx * SYSTIM_CH_STEP) +#define SYSTIM_TO_RTC_SHIFT 3U +#define SYSTIM_CH_CNT 5U +#define RTC_NEXT(val, now) (((val - PowerCC23X0_WAKEDELAYSTANDBY) >> SYSTIM_TO_RTC_SHIFT) + now) + +static void pm_cc23x0_enter_standby(void); +static int power_initialize(void); +extern int_fast16_t PowerCC23X0_notify(uint_fast16_t eventType); +static void pm_cc23x0_systim_standby_restore(void); + +/* Global to stash the SysTimer timeouts while we enter standby */ +static uint32_t systim[SYSTIM_CH_CNT]; +static uintptr_t key; +static uint32_t systim_mask; + +/* Shift values to convert between the different resolutions of the SysTimer + * channels. Channel 0 can technically support either 1us or 250ns. Until the + * channel is actively used, we will hard-code it to 1us resolution to improve + * runtime. + */ +const uint8_t systim_offset[SYSTIM_CH_CNT] = { + 0, /* 1us */ + 0, /* 1us */ + 2, /* 250ns -> 1us */ + 2, /* 250ns -> 1us */ + 2 /* 250ns -> 1us */ +}; + +static void pm_cc23x0_systim_standby_restore(void) +{ + HWREG(RTC_BASE + RTC_O_ARMCLR) = RTC_ARMCLR_CH0_CLR; + HWREG(RTC_BASE + RTC_O_ICLR) = RTC_ICLR_EV0_CLR; + + ULLSync(); + + HwiP_clearInterrupt(INT_CPUIRQ16); + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = EVTSVT_CPUIRQ16SEL_PUBID_SYSTIM0; + + while (HWREG(SYSTIM_BASE + SYSTIM_O_STATUS) != SYSTIM_STATUS_VAL_RUN) { + ; + } + + for (uint8_t idx = 0; idx < SYSTIM_CH_CNT; idx++) { + if (systim_mask & (1 << idx)) { + HWREG(SYSTIM_BASE + SYSTIM_CH(idx)) = systim[idx]; + } + } + + HWREG(SYSTIM_BASE + SYSTIM_O_IMASK) = systim_mask; + LRFDApplyClockDependencies(); + PowerCC23X0_notify(PowerLPF3_AWAKE_STANDBY); + + HwiP_restore(key); +} + +static void pm_cc23x0_enter_standby(void) +{ + uint32_t rtc_now = 0; + uint32_t systim_now = 0; + uint32_t systim_next = MAX_SYSTIMER_DELTA; + uint32_t systim_delta = 0; + + key = HwiP_disable(); + + uint32_t constraints = Power_getConstraintMask(); + bool standby = (constraints & (1 << PowerLPF3_DISALLOW_STANDBY)) == 0; + bool idle = (constraints & (1 << PowerLPF3_DISALLOW_IDLE)) == 0; + + if (standby && (HWREG(CKMD_BASE + CKMD_O_LFCLKSEL) & CKMD_LFCLKSEL_MAIN_LFOSC) && + !(HWREG(CKMD_BASE + CKMD_O_LFCLKSTAT) & CKMD_LFCLKSTAT_FLTSETTLED_M)) { + standby = false; + idle = false; + } + + if (standby) { + systim_mask = HWREG(SYSTIM_BASE + SYSTIM_O_IMASK); + if (systim_mask != 0) { + systim_next = 0xFFFFFFFF; + systim_now = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + for (uint8_t idx = 0; idx < SYSTIM_CH_CNT; idx++) { + if (systim_mask & (1 << idx)) { + systim[idx] = HWREG(SYSTIM_BASE + SYSTIM_CH(idx)); + systim_delta = systim[idx]; + systim_delta -= systim_now << systim_offset[idx]; + + if (systim_delta > MAX_SYSTIMER_DELTA) { + systim_delta = 0; + } + + systim_delta = systim_delta >> systim_offset[idx]; + systim_next = MIN(systim_next, systim_delta); + } + } + } else { + systim_next = MAX_SYSTIMER_DELTA; + } + + if (systim_next > PowerCC23X0_TOTALTIMESTANDBY) { + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = + EVTSVT_CPUIRQ16SEL_PUBID_AON_RTC_COMB; + HwiP_clearInterrupt(INT_CPUIRQ16); + rtc_now = HWREG(RTC_BASE + RTC_O_TIME8U); + HWREG(RTC_BASE + RTC_O_CH0CC8U) = RTC_NEXT(systim_next, rtc_now); + + Power_sleep(PowerLPF3_STANDBY); + pm_cc23x0_systim_standby_restore(); + } else if (idle) { + __WFI(); + } + } else if (idle) { + __WFI(); + } + + HwiP_restore(key); +} + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + switch (state) { + case PM_STATE_RUNTIME_IDLE: + PowerCC23X0_doWFI(); + break; + case PM_STATE_STANDBY: + pm_cc23x0_enter_standby(); + break; + case PM_STATE_SOFT_OFF: + Power_shutdown(0, 0); + break; + default: + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(state); + ARG_UNUSED(substate_id); + + HwiP_restore(0); +} + +#endif /* CONFIG_PM */ + +static int power_initialize(void) +{ + Power_init(); + + if (DT_HAS_COMPAT_STATUS_OKAY(ti_cc23x0_lf_xosc)) { + PowerLPF3_selectLFXT(); + } + + PMCTLSetVoltageRegulator(PMCTL_VOLTAGE_REGULATOR_DCDC); + + return 0; +} + +SYS_INIT(power_initialize, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/soc/ti/simplelink/cc23x0/soc.c b/soc/ti/simplelink/cc23x0/soc.c index cddae58b4e05d..c687e3704ccf5 100644 --- a/soc/ti/simplelink/cc23x0/soc.c +++ b/soc/ti/simplelink/cc23x0/soc.c @@ -7,6 +7,9 @@ #include +const uint_least8_t GPIO_pinLowerBound; +const uint_least8_t GPIO_pinUpperBound = 25; + void soc_reset_hook(void) { /* Perform necessary trim of the device. */ From 2f5c2f266c80d786e26cbd96345d0f35a5e50a76 Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Mon, 21 Oct 2024 14:04:27 +0300 Subject: [PATCH 08/10] soc: ti: cc23x0: Add conditions for RTC as timer in power.c In power management, add conditions to handle the case where RTC is used as main timer. Signed-off-by: Stoyan Bogdanov --- soc/ti/simplelink/cc23x0/power.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/soc/ti/simplelink/cc23x0/power.c b/soc/ti/simplelink/cc23x0/power.c index 54512c9cf23ba..8cbd3d8722497 100644 --- a/soc/ti/simplelink/cc23x0/power.c +++ b/soc/ti/simplelink/cc23x0/power.c @@ -36,6 +36,8 @@ const PowerCC23X0_Config PowerCC23X0_config = { #ifdef CONFIG_PM +#ifndef CONFIG_CC23X0_RTC_TIMER + #define MAX_SYSTIMER_DELTA 0xFFBFFFFFU #define RTC_TO_SYSTIM_TICKS 8U #define SYSTIM_CH_STEP 4U @@ -44,9 +46,13 @@ const PowerCC23X0_Config PowerCC23X0_config = { #define SYSTIM_CH_CNT 5U #define RTC_NEXT(val, now) (((val - PowerCC23X0_WAKEDELAYSTANDBY) >> SYSTIM_TO_RTC_SHIFT) + now) +#endif + static void pm_cc23x0_enter_standby(void); static int power_initialize(void); extern int_fast16_t PowerCC23X0_notify(uint_fast16_t eventType); + +#ifndef CONFIG_CC23X0_RTC_TIMER static void pm_cc23x0_systim_standby_restore(void); /* Global to stash the SysTimer timeouts while we enter standby */ @@ -66,7 +72,9 @@ const uint8_t systim_offset[SYSTIM_CH_CNT] = { 2, /* 250ns -> 1us */ 2 /* 250ns -> 1us */ }; +#endif +#ifndef CONFIG_CC23X0_RTC_TIMER static void pm_cc23x0_systim_standby_restore(void) { HWREG(RTC_BASE + RTC_O_ARMCLR) = RTC_ARMCLR_CH0_CLR; @@ -93,9 +101,11 @@ static void pm_cc23x0_systim_standby_restore(void) HwiP_restore(key); } +#endif static void pm_cc23x0_enter_standby(void) { +#ifndef CONFIG_CC23X0_RTC_TIMER uint32_t rtc_now = 0; uint32_t systim_now = 0; uint32_t systim_next = MAX_SYSTIMER_DELTA; @@ -142,8 +152,9 @@ static void pm_cc23x0_enter_standby(void) HwiP_clearInterrupt(INT_CPUIRQ16); rtc_now = HWREG(RTC_BASE + RTC_O_TIME8U); HWREG(RTC_BASE + RTC_O_CH0CC8U) = RTC_NEXT(systim_next, rtc_now); - +#endif Power_sleep(PowerLPF3_STANDBY); +#ifndef CONFIG_CC23X0_RTC_TIMER pm_cc23x0_systim_standby_restore(); } else if (idle) { __WFI(); @@ -153,6 +164,7 @@ static void pm_cc23x0_enter_standby(void) } HwiP_restore(key); +#endif } void pm_state_set(enum pm_state state, uint8_t substate_id) From 0a2237320ab1c44c5d0fe308f6493831721db0b5 Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Wed, 23 Oct 2024 16:29:18 +0300 Subject: [PATCH 09/10] soc: ti: cc23x0: Add support for RTC alarms in power.c In power management, add support to take into account the alarms set in RTC. Alarm from RTC is processed like any other from SYSTIM. This prevents from missing interrupts. Signed-off-by: Stoyan Bogdanov --- soc/ti/simplelink/cc23x0/power.c | 35 +++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/soc/ti/simplelink/cc23x0/power.c b/soc/ti/simplelink/cc23x0/power.c index 8cbd3d8722497..f685b14823ca6 100644 --- a/soc/ti/simplelink/cc23x0/power.c +++ b/soc/ti/simplelink/cc23x0/power.c @@ -44,6 +44,7 @@ const PowerCC23X0_Config PowerCC23X0_config = { #define SYSTIM_CH(idx) (SYSTIM_O_CH0CC + idx * SYSTIM_CH_STEP) #define SYSTIM_TO_RTC_SHIFT 3U #define SYSTIM_CH_CNT 5U +#define RTC_CH_CNT 2U #define RTC_NEXT(val, now) (((val - PowerCC23X0_WAKEDELAYSTANDBY) >> SYSTIM_TO_RTC_SHIFT) + now) #endif @@ -57,8 +58,10 @@ static void pm_cc23x0_systim_standby_restore(void); /* Global to stash the SysTimer timeouts while we enter standby */ static uint32_t systim[SYSTIM_CH_CNT]; +static uint32_t rtc[RTC_CH_CNT]; static uintptr_t key; static uint32_t systim_mask; +static uint32_t rtc_mask; /* Shift values to convert between the different resolutions of the SysTimer * channels. Channel 0 can technically support either 1us or 250ns. Until the @@ -83,7 +86,10 @@ static void pm_cc23x0_systim_standby_restore(void) ULLSync(); HwiP_clearInterrupt(INT_CPUIRQ16); + HwiP_clearInterrupt(INT_CPUIRQ3); + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = EVTSVT_CPUIRQ16SEL_PUBID_SYSTIM0; + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ3SEL) = EVTSVT_CPUIRQ16SEL_PUBID_AON_RTC_COMB; while (HWREG(SYSTIM_BASE + SYSTIM_O_STATUS) != SYSTIM_STATUS_VAL_RUN) { ; @@ -96,9 +102,19 @@ static void pm_cc23x0_systim_standby_restore(void) } HWREG(SYSTIM_BASE + SYSTIM_O_IMASK) = systim_mask; + HWREG(RTC_BASE + RTC_O_IMASK) = rtc_mask; + + if (rtc_mask != 0) { + if (rtc_mask & 0x1) { + HWREG(RTC_BASE + RTC_O_CH0CC8U) = rtc[0]; + } + if (rtc_mask & 0x2) { + HWREG(RTC_BASE + RTC_O_CH1CC8U) = rtc[1]; + } + } + LRFDApplyClockDependencies(); PowerCC23X0_notify(PowerLPF3_AWAKE_STANDBY); - HwiP_restore(key); } #endif @@ -110,6 +126,7 @@ static void pm_cc23x0_enter_standby(void) uint32_t systim_now = 0; uint32_t systim_next = MAX_SYSTIMER_DELTA; uint32_t systim_delta = 0; + uint32_t rtc_delta = 0; key = HwiP_disable(); @@ -146,7 +163,23 @@ static void pm_cc23x0_enter_standby(void) systim_next = MAX_SYSTIMER_DELTA; } + rtc_mask = HWREG(RTC_BASE + RTC_O_IMASK); + if (rtc_mask != 0) { + rtc_now = HWREG(RTC_BASE + RTC_O_TIME8U); + if (rtc_mask & 0x1) { + rtc[0] = HWREG(RTC_BASE + RTC_O_CH0CC8U); + rtc_delta = (rtc[0] - rtc_now) << 3; + systim_next = MIN(systim_next, rtc_delta); + } + if (rtc_mask & 0x2) { + rtc[1] = HWREG(RTC_BASE + RTC_O_CH1CC8U); + rtc_delta = (rtc[1] - rtc_now) << 3; + systim_next = MIN(systim_next, rtc_delta); + } + } + if (systim_next > PowerCC23X0_TOTALTIMESTANDBY) { + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ3SEL) = 0; HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = EVTSVT_CPUIRQ16SEL_PUBID_AON_RTC_COMB; HwiP_clearInterrupt(INT_CPUIRQ16); From b7b48d630887db3c763990ce438942120a85e7f8 Mon Sep 17 00:00:00 2001 From: Stoyan Bogdanov Date: Mon, 21 Oct 2024 12:20:26 +0200 Subject: [PATCH 10/10] dts: arm: ti: cc23x0: Add power management support Add support for PM to cc23x0 SoC. Signed-off-by: Stoyan Bogdanov Signed-off-by: Julien Panis --- dts/arm/ti/cc23x0.dtsi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dts/arm/ti/cc23x0.dtsi b/dts/arm/ti/cc23x0.dtsi index 96a1e189a8b8f..d3ab5fda5383d 100644 --- a/dts/arm/ti/cc23x0.dtsi +++ b/dts/arm/ti/cc23x0.dtsi @@ -22,6 +22,31 @@ compatible = "arm,cortex-m0+"; clock-frequency = ; reg = <0>; + cpu-power-states = <&state0 &state1 &state2>; + }; + + power-states { + state0: state0 { + compatible = "zephyr,power-state"; + power-state-name = "runtime-idle"; + min-residency-us = <315>; + }; + + state1: state1 { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <315>; + exit-latency-us = <185>; + }; + + /* PM_STATE_SOFT_OFF can be entered only by calling pm_state_force */ + state2: state2 { + compatible = "zephyr,power-state"; + power-state-name = "soft-off"; + min-residency-us = <0>; + exit-latency-us = <0>; + status = "disabled"; + }; }; };