From e77ea215bd76f290e27183f175dc351db0aaa877 Mon Sep 17 00:00:00 2001 From: Aksel Skauge Mellbye Date: Fri, 10 Jan 2025 13:00:52 +0100 Subject: [PATCH] drivers: hwinfo: silabs: Add hwinfo driver for Series 2 Add hwinfo driver for Silicon Labs Series 2 devices. The driver is separate from the Series 0/1 Gecko driver because the available reset causes are completely different. Signed-off-by: Aksel Skauge Mellbye --- .../dev_kits/xg24_dk2601b/xg24_dk2601b.yaml | 1 - .../dev_kits/xg24_ek2703a/xg24_ek2703a.yaml | 1 - .../xg24_rb4187c/xg24_rb4187c.yaml | 1 - drivers/hwinfo/CMakeLists.txt | 1 + drivers/hwinfo/Kconfig | 13 +- drivers/hwinfo/hwinfo_silabs_series2.c | 124 ++++++++++++++++++ 6 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 drivers/hwinfo/hwinfo_silabs_series2.c diff --git a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml index 599c5c6657e..af937c8b4a2 100644 --- a/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml +++ b/boards/silabs/dev_kits/xg24_dk2601b/xg24_dk2601b.yaml @@ -18,5 +18,4 @@ supported: testing: ignore_tags: - pm - - hwinfo vendor: silabs diff --git a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml index 551f2754872..1a5d73e8ebb 100644 --- a/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml +++ b/boards/silabs/dev_kits/xg24_ek2703a/xg24_ek2703a.yaml @@ -17,5 +17,4 @@ supported: testing: ignore_tags: - pm - - hwinfo vendor: silabs diff --git a/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml index 014021b5548..5a6b31016c9 100644 --- a/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml +++ b/boards/silabs/radio_boards/xg24_rb4187c/xg24_rb4187c.yaml @@ -17,5 +17,4 @@ supported: testing: ignore_tags: - pm - - hwinfo vendor: silabs diff --git a/drivers/hwinfo/CMakeLists.txt b/drivers/hwinfo/CMakeLists.txt index e6db830d865..f7ea43bf249 100644 --- a/drivers/hwinfo/CMakeLists.txt +++ b/drivers/hwinfo/CMakeLists.txt @@ -31,6 +31,7 @@ zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM hwinfo_sam.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM0 hwinfo_sam0.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM4L hwinfo_sam4l.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM_RSTC hwinfo_sam_rstc.c) +zephyr_library_sources_ifdef(CONFIG_HWINFO_SILABS_S2 hwinfo_silabs_series2.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_SMARTBOND hwinfo_smartbond.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_STM32 hwinfo_stm32.c) # zephyr-keep-sorted-stop diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 1fa1418b83f..5a8ebe878aa 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -204,14 +204,21 @@ config HWINFO_PSOC6 config HWINFO_GECKO bool "GECKO hwinfo" default y - depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 - depends on !SOC_SERIES_EFR32MG21 - depends on !SOC_SERIES_EFR32BG22 + depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 select HWINFO_HAS_DRIVER select SOC_GECKO_RMU help Enable Silabs GECKO hwinfo driver. +config HWINFO_SILABS_S2 + bool "Silabs Series 2 hwinfo" + default y + depends on SOC_FAMILY_SILABS_S2 + select HWINFO_HAS_DRIVER + select SOC_GECKO_RMU + help + Enable Silabs Series 2 hwinfo driver. + config HWINFO_ANDES bool "Andes system ID" default y diff --git a/drivers/hwinfo/hwinfo_silabs_series2.c b/drivers/hwinfo/hwinfo_silabs_series2.c new file mode 100644 index 00000000000..bb7b45d9fe9 --- /dev/null +++ b/drivers/hwinfo/hwinfo_silabs_series2.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +#include + +/* Ensure that all possible reset causes have a definition */ +#ifndef EMU_RSTCAUSE_BOOSTON +#define EMU_RSTCAUSE_BOOSTON 0 +#endif +#ifndef EMU_RSTCAUSE_WDOG1 +#define EMU_RSTCAUSE_WDOG1 0 +#endif +#ifndef EMU_RSTCAUSE_IOVDD1BOD +#define EMU_RSTCAUSE_IOVDD1BOD 0 +#endif +#ifndef EMU_RSTCAUSE_IOVDD2BOD +#define EMU_RSTCAUSE_IOVDD2BOD 0 +#endif +#ifndef EMU_RSTCAUSE_SETAMPER +#define EMU_RSTCAUSE_SETAMPER 0 +#endif +#ifndef EMU_RSTCAUSE_SESYSREQ +#define EMU_RSTCAUSE_SESYSREQ 0 +#endif +#ifndef EMU_RSTCAUSE_SELOCKUP +#define EMU_RSTCAUSE_SELOCKUP 0 +#endif +#ifndef EMU_RSTCAUSE_DCI +#define EMU_RSTCAUSE_DCI 0 +#endif + +/* The Zephyr API expects hwinfo_get_reset_cause() to return 0 after hwinfo_clear_reset_cause() has + * been called. This matches the hardware behavior on Series 2, but not the HAL API. The HAL stores + * the reset cause upon first read, and returns this cached value on subsequent calls to the API + * to allow multiple subsystems to read the reset cause despite it having been cleared in hardware + * already. Emulate the hardware behavior while staying compatible with other users of the HAL API + * by keeping track of whether the reset cause should be considered cleared or not ourselves. + */ +static bool reset_cleared; + +ssize_t z_impl_hwinfo_get_device_id(uint8_t *buffer, size_t length) +{ + uint64_t unique_id = sys_cpu_to_be64(SYSTEM_GetUnique()); + + if (length > sizeof(unique_id)) { + length = sizeof(unique_id); + } + + memcpy(buffer, &unique_id, length); + + return length; +} + +int z_impl_hwinfo_get_reset_cause(uint32_t *cause) +{ + uint32_t flags = 0; + uint32_t rmu = RMU_ResetCauseGet(); + + if (reset_cleared) { + *cause = 0; + return 0; + } + + if (rmu & EMU_RSTCAUSE_POR) { + flags |= RESET_POR; + } + + if (rmu & EMU_RSTCAUSE_PIN) { + flags |= RESET_PIN; + } + + if (rmu & (EMU_RSTCAUSE_EM4 | EMU_RSTCAUSE_BOOSTON)) { + flags |= RESET_LOW_POWER_WAKE; + } + + if (rmu & (EMU_RSTCAUSE_WDOG0 | EMU_RSTCAUSE_WDOG1)) { + flags |= RESET_WATCHDOG; + } + + if (rmu & EMU_RSTCAUSE_LOCKUP) { + flags |= RESET_CPU_LOCKUP; + } + + if (rmu & EMU_RSTCAUSE_SYSREQ) { + flags |= RESET_SOFTWARE; + } + + if (rmu & (EMU_RSTCAUSE_DVDDBOD | EMU_RSTCAUSE_DVDDLEBOD | EMU_RSTCAUSE_DECBOD | + EMU_RSTCAUSE_AVDDBOD | EMU_RSTCAUSE_IOVDD0BOD | + EMU_RSTCAUSE_IOVDD1BOD | EMU_RSTCAUSE_IOVDD2BOD)) { + flags |= RESET_BROWNOUT; + } + + if (rmu & (EMU_RSTCAUSE_SETAMPER | EMU_RSTCAUSE_SESYSREQ | + EMU_RSTCAUSE_SELOCKUP | EMU_RSTCAUSE_DCI)) { + flags |= RESET_SECURITY; + } + + *cause = flags; + return 0; +} + +int z_impl_hwinfo_clear_reset_cause(void) +{ + RMU_ResetCauseClear(); + reset_cleared = true; + return 0; +} + +int z_impl_hwinfo_get_supported_reset_cause(uint32_t *supported) +{ + *supported = RESET_PIN | RESET_SOFTWARE | RESET_BROWNOUT | RESET_POR | RESET_WATCHDOG | + RESET_SECURITY | RESET_LOW_POWER_WAKE | RESET_CPU_LOCKUP; + return 0; +}