soc: silabs_exx32: Add support for SiLabs EFR32BG22 SoC

This commit adds support for Silicon Labs EFR32BG22 SoC.

Co-authored-by: Mateusz Sierszulski <msierszulski@antmicro.com>
Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
This commit is contained in:
Filip Kokosinski 2022-09-07 11:06:30 +02:00 committed by Carles Cufí
parent 067f3766da
commit 509e101a91
14 changed files with 475 additions and 24 deletions

View file

@ -495,6 +495,7 @@
/dts/arm/silabs/efm32_pg_1b.dtsi @rdmeneze
/dts/arm/silabs/efm32gg11b* @oanerer
/dts/arm/silabs/efr32bg13p* @mnkp
/dts/arm/silabs/efr32bg22* @kgugala @fkokosinski @pczarnecki
/dts/arm/silabs/efr32xg13p* @mnkp
/dts/arm/silabs/efm32pg1b* @rdmeneze
/dts/arm/silabs/efr32mg21* @l-alfred

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2022 Silicon Labs
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <dt-bindings/pinctrl/gecko-pinctrl.h>
&pinctrl {
/* configuration for uart0 device, default state */
usart0_default: usart0_default {
group1 {
/* configure PE.11 as UART_RX and PE.10 as UART_TX */
psels = <GECKO_PSEL(UART_TX, E, 10)>,
<GECKO_PSEL(UART_RX, E, 11)>,
<GECKO_LOC(UART, 0)>;
};
};
/* configuration for uart1 device, default state */
usart1_default: usart1_default {
group1 {
/* configure PA.6 as UART_RX and PA.5 as UART_TX */
psels = <GECKO_PSEL(UART_TX, A, 5)>,
<GECKO_PSEL(UART_RX, A, 6)>,
<GECKO_LOC(UART, 1)>;
};
};
};

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2021 Sateesh Kotapati
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <arm/armv8-m.dtsi>
#include <arm/silabs/gpio_gecko.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/i2c/i2c.h>
#include <dt-bindings/pinctrl/gecko-pinctrl.h>
/ {
chosen {
zephyr,flash-controller = &msc;
};
power-states {
standby: standby {
compatible = "zephyr,power-state";
power-state-name = "standby";
min-residency-us = <50000>;
};
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-m33";
reg = <0>;
cpu-power-states = <&standby>;
};
};
sram0: memory@20000000 {
compatible = "mmio-sram";
};
soc {
msc: flash-controller@50030000 {
compatible = "silabs,gecko-flash-controller";
reg = <0x50030000 0xC69>;
interrupts = <49 0>;
#address-cells = <1>;
#size-cells = <1>;
flash0: flash@0 {
compatible = "soc-nv-flash";
write-block-size = <4>;
erase-block-size = <8192>;
};
};
usart0: usart@5005c000 {
compatible = "silabs,gecko-usart";
reg = <0x5005C000 0x400>;
interrupts = <13 0>, <14 0>;
interrupt-names = "rx", "tx";
peripheral-id = <0>;
status = "disabled";
};
usart1: usart@50060000 {
compatible = "silabs,gecko-usart";
reg = <0x50060000 0x400>;
interrupts = <15 0>, <16 0>;
interrupt-names = "rx", "tx";
peripheral-id = <1>;
status = "disabled";
};
i2c0: i2c@5a010000 {
compatible = "silabs,gecko-i2c";
clock-frequency = <I2C_BITRATE_STANDARD>;
reg = <0x5a010000 0x3044>;
interrupts = <27 0>;
status = "disabled";
};
i2c1: i2c@50068000 {
compatible = "silabs,gecko-i2c";
clock-frequency = <I2C_BITRATE_STANDARD>;
reg = <0x50068000 0x3044>;
interrupts = <28 0>;
status = "disabled";
};
stimer0: stimer@58000000 {
compatible = "silabs,gecko-stimer";
reg = <0x58000000 0x3054>;
interrupts = <12 0>;
clock-frequency = <32768>;
prescaler = <1>;
status = "disabled";
};
gpio: gpio@5003c000 {
compatible = "silabs,gecko-gpio";
reg = <0x5003C000 0x3660>;
interrupts = <10 2 18 2>;
interrupt-names = "GPIO_EVEN", "GPIO_ODD";
ranges;
#address-cells = <1>;
#size-cells = <1>;
gpioa: gpio@5003c000 {
compatible = "silabs,gecko-gpio-port";
reg = <0x5003C000 0x30>;
peripheral-id = <0>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
gpiob: gpio@5003c030 {
compatible = "silabs,gecko-gpio-port";
reg = <0x5003C030 0x30>;
peripheral-id = <1>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
gpioc: gpio@5003c060 {
compatible = "silabs,gecko-gpio-port";
reg = <0x5003C060 0x30>;
peripheral-id = <2>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
gpiod: gpio@5003c090 {
compatible = "silabs,gecko-gpio-port";
reg = <0x5003C090 0x30>;
peripheral-id = <3>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
gpiof: gpio@5003c0c0 {
compatible = "silabs,gecko-gpio-port";
reg = <0x5003C0C0 0x30>;
peripheral-id = <3>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
};
};
};
/ {
pinctrl: pin-controller {
/* Pin controller is a "virtual" device since SiLabs SoCs do pin
* control in a distributed way (GPIO registers and PSEL
* registers on each peripheral).
*/
compatible = "silabs,gecko-pinctrl";
};
};
&nvic {
arm,num-irq-priority-bits = <4>;
};

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2021 Sateesh Kotapati
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <mem.h>
#include <silabs/efr32bg22.dtsi>
/ {
soc {
compatible = "silabs,efr32bg22c224f512im40", "silabs,efr32bg22",
"silabs,efr32", "simple-bus";
};
};
&sram0 {
reg = <0x20000000 DT_SIZE_K(32)>;
};
&flash0 {
reg = <0 DT_SIZE_K(512)>;
};

View file

@ -134,6 +134,22 @@ choice SOC_GECKO_EMU_DCDC_MODE
bool "Bypass"
endchoice
config SOC_GECKO_DEV_INIT
bool
help
Use the device initialization routines from the device_init service
in Silicon Labs HAL. These routines initialize and tune HFXOs,
configures DPLLs and manages the Energy Management Unit.
Disabling these services may negatively impact counter and timer
routines in EXX32 series SoCs.
config COUNTER_GECKO_STIMER
bool
help
Enable counter driver based on RTCC module for Silicon Labs Gecko
chips.
config SOC_GECKO_CMU
bool
help

View file

@ -3,3 +3,4 @@
zephyr_sources(soc.c)
zephyr_sources_ifdef(CONFIG_PM soc_power.c)
zephyr_include_directories(.)

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2022 Silicon Labs
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* Silabs SoC specific helpers for pinctrl driver
*/
#ifndef ZEPHYR_SOC_ARM_SILABS_GECKO_COMMON_PINCTRL_SOC_H_
#define ZEPHYR_SOC_ARM_SILABS_GECKO_COMMON_PINCTRL_SOC_H_
#include <stdint.h>
#include <zephyr/devicetree.h>
#include <zephyr/dt-bindings/pinctrl/gecko-pinctrl.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @cond INTERNAL_HIDDEN */
/** Type for gecko pin. */
typedef uint32_t pinctrl_soc_pin_t;
/**
* @brief Utility macro to initialize each pin.
*
* @param node_id Node identifier.
* @param prop Property name.
* @param idx Property entry index.
*/
#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) (DT_PROP_BY_IDX(node_id, prop, idx)),
/**
* @brief Utility macro to initialize state pins contained in a given property.
*
* @param node_id Node identifier.
* @param prop Property name describing state pins.
*/
#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \
{ \
DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, psels, \
Z_PINCTRL_STATE_PIN_INIT) \
}
/**
* @brief Utility macro to obtain pin function.
*
* @param pincfg Pin configuration bit field.
*/
#define GECKO_GET_FUN(pincfg) (((pincfg) >> GECKO_FUN_POS) & GECKO_FUN_MSK)
/**
* @brief Utility macro to obtain port configuration.
*
* @param pincfg port configuration bit field.
*/
#define GECKO_GET_PORT(pincfg) (((pincfg) >> GECKO_PORT_POS) & GECKO_PORT_MSK)
/**
* @brief Utility macro to obtain pin configuration.
*
* @param pincfg pin configuration bit field.
*/
#define GECKO_GET_PIN(pincfg) (((pincfg) >> GECKO_PIN_POS) & GECKO_PIN_MSK)
/**
* @brief Utility macro to obtain location configuration.
*
* @param pincfg Loc configuration bit field.
*/
#define GECKO_GET_LOC(pincfg) (((pincfg) >> GECKO_LOC_POS) & GECKO_LOC_MSK)
/**
* @brief Utility macro to obtain speed configuration.
*
* @param pincfg speed configuration bit field.
*/
#define GECKO_GET_SPEED(pincfg) (((pincfg) >> GECKO_SPEED_POS) & GECKO_SPEED_MSK)
/** @endcond */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_SOC_ARM_SILABS_GECKO_COMMON_PINCTRL_SOC_H_ */

View file

@ -9,16 +9,25 @@
* @brief Common SoC initialization for the EXX32
*/
#include <zephyr/kernel.h>
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/init.h>
#include <soc.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <em_chip.h>
#include <em_cmu.h>
#include <em_emu.h>
#include <em_chip.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
#include <soc.h>
#include <zephyr/logging/log.h>
#ifdef CONFIG_SOC_GECKO_DEV_INIT
#include <sl_device_init_dcdc.h>
#include <sl_device_init_dpll.h>
#include <sl_device_init_emu.h>
#include <sl_device_init_hfxo.h>
#include <sl_device_init_nvic.h>
#endif
LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);
@ -47,13 +56,13 @@ static ALWAYS_INLINE void clock_init(void)
* See AN0016.2
*/
if ((DEVINFO->MODULEINFO & DEVINFO_MODULEINFO_HFXOCALVAL) ==
DEVINFO_MODULEINFO_HFXOCALVAL_VALID) {
hfxoInit.ctuneXoAna = (DEVINFO->MODXOCAL
& _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_MASK)
>> _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_SHIFT;
hfxoInit.ctuneXiAna = (DEVINFO->MODXOCAL
& _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK)
>> _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_SHIFT;
DEVINFO_MODULEINFO_HFXOCALVAL_VALID) {
hfxoInit.ctuneXoAna =
(DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXOANA_MASK) >>
_DEVINFO_MODXOCAL_HFXOCTUNEXOANA_SHIFT;
hfxoInit.ctuneXiAna =
(DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK) >>
_DEVINFO_MODXOCAL_HFXOCTUNEXIANA_SHIFT;
}
CMU_HFXOInit(&hfxoInit);
@ -79,10 +88,10 @@ static ALWAYS_INLINE void clock_init(void)
* See AN0016.2
*/
if ((DEVINFO->MODULEINFO & DEVINFO_MODULEINFO_LFXOCALVAL) ==
DEVINFO_MODULEINFO_LFXOCALVAL_VALID) {
lfxoInit.capTune = (DEVINFO->MODXOCAL
& _DEVINFO_MODXOCAL_LFXOCAPTUNE_MASK)
>> _DEVINFO_MODXOCAL_LFXOCAPTUNE_SHIFT;
DEVINFO_MODULEINFO_LFXOCALVAL_VALID) {
lfxoInit.capTune =
(DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_LFXOCAPTUNE_MASK) >>
_DEVINFO_MODXOCAL_LFXOCAPTUNE_SHIFT;
}
}
@ -115,11 +124,11 @@ static ALWAYS_INLINE void clock_init(void)
#endif
#if defined(_SILICON_LABS_32B_SERIES_2)
/* Enable the High Frequency Peripheral Clock */
CMU_ClockEnable(cmuClock_PCLK, true);
/* Enable the High Frequency Peripheral Clock */
CMU_ClockEnable(cmuClock_PCLK, true);
#else
/* Enable the High Frequency Peripheral Clock */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Enable the High Frequency Peripheral Clock */
CMU_ClockEnable(cmuClock_HFPER, true);
#endif /* _SILICON_LABS_32B_SERIES_2 */
#if defined(CONFIG_GPIO_GECKO) || defined(CONFIG_LOG_BACKEND_SWO)
@ -161,8 +170,7 @@ static void swo_init(void)
/* Enable Serial wire output pin */
GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN;
/* Set SWO location */
GPIO->ROUTELOC0 =
SWO_LOCATION << _GPIO_ROUTELOC0_SWVLOC_SHIFT;
GPIO->ROUTELOC0 = SWO_LOCATION << _GPIO_ROUTELOC0_SWVLOC_SHIFT;
#else
GPIO->ROUTE = GPIO_ROUTE_SWOPEN | (SWO_LOCATION << 8);
#endif
@ -192,6 +200,13 @@ static int silabs_exx32_init(const struct device *arg)
/* handle chip errata */
CHIP_Init();
#ifdef CONFIG_SOC_GECKO_DEV_INIT
sl_device_init_dcdc();
sl_device_init_hfxo();
sl_device_init_dpll();
sl_device_init_emu();
#else
#ifdef CONFIG_SOC_GECKO_EMU_DCDC
dcdc_init();
#endif
@ -209,7 +224,7 @@ static int silabs_exx32_init(const struct device *arg)
/* Configure SWO debug output */
swo_init();
#endif
#endif
/* restore interrupt state */
irq_unlock(oldLevel);
return 0;

View file

@ -0,0 +1,16 @@
# Silicon Labs EFR32BG22 (Blue Gecko) MCU configuration options
# Copyright (c) 2021 Sateesh Kotapati
# SPDX-License-Identifier: Apache-2.0
config GPIO_GECKO
default y
config I2C_GECKO
default n
config SOC_FLASH_GECKO
default n
config SPI_GECKO
default n

View file

@ -0,0 +1,23 @@
# Silicon Labs EFR32BG22 (Blue Gecko) MCU configuration options
# Copyright (c) 2021 Sateesh Kotapati
# SPDX-License-Identifier: Apache-2.0
if SOC_SERIES_EFR32BG22
config SOC_SERIES
default "efr32bg22"
config SOC_PART_NUMBER
default "EFR32BG22C224F512IM40" if SOC_PART_NUMBER_EFR32BG22C224F512IM40
config NUM_IRQS
# must be >= the highest interrupt number used
default 60
config PM
select COUNTER
source "soc/arm/silabs_exx32/efr32bg22/Kconfig.defconfig.efr32bg22"
endif # SOC_SERIES_EFR32BG22

View file

@ -0,0 +1,22 @@
# Silicon Labs EFR32BG22 (Blue Gecko) MCU
# Copyright (c) 2021 Sateesh Kotapati
# SPDX-License-Identifier: Apache-2.0
config SOC_SERIES_EFR32BG22
bool "EFR32BG22P Series MCU"
select ARM
select ARMV8_M_DSP
select ARM_TRUSTZONE_M
select CPU_CORTEX_M33
select CPU_HAS_ARM_MPU
select CPU_HAS_ARM_SAU
select CPU_HAS_FPU
select HAS_SILABS_GECKO
select HAS_SWO
select SOC_FAMILY_EXX32
select SOC_GECKO_CMU
select SOC_GECKO_CORE
select SOC_GECKO_DEV_INIT
help
Enable support for EFR32BG22 Blue Gecko MCU series

View file

@ -0,0 +1,8 @@
# Silicon Labs EFR32BG22 (Blue Gecko) MCU series
# Copyright (c) 2021 Sateesh Kotapati
# SPDX-License-Identifier: Apache-2.0
config SOC_PART_NUMBER_EFR32BG22C224F512IM40
bool
depends on SOC_SERIES_EFR32BG22

View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2021 Sateesh Kotapati
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* This is the linker script for both standard images.
*/
#include <zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld>

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2021 Sateesh Kotapati
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Register access macros for the EFR32BG22 SoC
*
*/
#ifndef EFR32BG22_SOC_H_
#define EFR32BG22_SOC_H_
#ifndef _ASMLANGUAGE
#include <em_common.h>
#endif /* !_ASMLANGUAGE */
#endif /* EFR32BG22_SOC_H_ */