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 <aksel.mellbye@silabs.com>
This commit is contained in:
Aksel Skauge Mellbye 2025-01-10 13:00:52 +01:00 committed by Benjamin Cabé
commit e77ea215bd
6 changed files with 135 additions and 6 deletions

View file

@ -18,5 +18,4 @@ supported:
testing: testing:
ignore_tags: ignore_tags:
- pm - pm
- hwinfo
vendor: silabs vendor: silabs

View file

@ -17,5 +17,4 @@ supported:
testing: testing:
ignore_tags: ignore_tags:
- pm - pm
- hwinfo
vendor: silabs vendor: silabs

View file

@ -17,5 +17,4 @@ supported:
testing: testing:
ignore_tags: ignore_tags:
- pm - pm
- hwinfo
vendor: silabs vendor: silabs

View file

@ -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_SAM0 hwinfo_sam0.c)
zephyr_library_sources_ifdef(CONFIG_HWINFO_SAM4L hwinfo_sam4l.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_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_SMARTBOND hwinfo_smartbond.c)
zephyr_library_sources_ifdef(CONFIG_HWINFO_STM32 hwinfo_stm32.c) zephyr_library_sources_ifdef(CONFIG_HWINFO_STM32 hwinfo_stm32.c)
# zephyr-keep-sorted-stop # zephyr-keep-sorted-stop

View file

@ -204,14 +204,21 @@ config HWINFO_PSOC6
config HWINFO_GECKO config HWINFO_GECKO
bool "GECKO hwinfo" bool "GECKO hwinfo"
default y default y
depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1 || SOC_FAMILY_SILABS_S2 depends on SOC_FAMILY_SILABS_S0 || SOC_FAMILY_SILABS_S1
depends on !SOC_SERIES_EFR32MG21
depends on !SOC_SERIES_EFR32BG22
select HWINFO_HAS_DRIVER select HWINFO_HAS_DRIVER
select SOC_GECKO_RMU select SOC_GECKO_RMU
help help
Enable Silabs GECKO hwinfo driver. 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 config HWINFO_ANDES
bool "Andes system ID" bool "Andes system ID"
default y default y

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2025 Silicon Laboratories Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/sys/byteorder.h>
#include <string.h>
#include <em_system.h>
#include <em_rmu.h>
/* 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;
}