Skip to content

Add Power Management support to TI cc23x0 SoC #91401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
zephyr,code = <INPUT_KEY_1>;
};
};

lfxosc: lf_xosc {
compatible = "ti,cc23x0-lf-xosc";
};
};

&gpio0 {
Expand Down
1 change: 1 addition & 0 deletions drivers/counter/Kconfig.cc23x0_rtc
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions drivers/timer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/timer/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
26 changes: 26 additions & 0 deletions drivers/timer/Kconfig.cc23x0
Original file line number Diff line number Diff line change
@@ -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
12 changes: 12 additions & 0 deletions drivers/timer/Kconfig.cc23x0_rtc
Original file line number Diff line number Diff line change
@@ -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.
13 changes: 0 additions & 13 deletions drivers/timer/Kconfig.cc23x0_systim

This file was deleted.

122 changes: 122 additions & 0 deletions drivers/timer/cc23x0_rtc_timer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2024 BayLibre, SAS
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT ti_cc23x0_rtc_timer

#include <soc.h>

#include <zephyr/device.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/timer/system_timer.h>
#include <zephyr/irq.h>
#include <zephyr/spinlock.h>
#include <zephyr/sys_clock.h>
#include <zephyr/sys/util.h>

#include <inc/hw_rtc.h>
#include <inc/hw_types.h>
#include <inc/hw_evtsvt.h>
#include <inc/hw_memmap.h>

#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);
25 changes: 25 additions & 0 deletions dts/arm/ti/cc23x0.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,31 @@
compatible = "arm,cortex-m0+";
clock-frequency = <DT_FREQ_M(48)>;
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";
};
};
};

Expand Down
8 changes: 8 additions & 0 deletions dts/bindings/clock/ti,cc23x0-lf-xosc.yaml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions soc/ti/simplelink/cc23x0/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 "")
2 changes: 2 additions & 0 deletions soc/ti/simplelink/cc23x0/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions soc/ti/simplelink/cc23x0/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading