blob: b0de0dc280111a044f71934fe9121b67cb27e9bc [file] [log] [blame]
/*
* Copyright (c) 2018, Christian Taedcke
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief SoC initialization for the EFR32FG1P
*/
#include <kernel.h>
#include <init.h>
#include <soc.h>
#include <em_cmu.h>
#include <em_chip.h>
#include <arch/cpu.h>
#include <cortex_m/exc.h>
#ifdef CONFIG_CMU_HFCLK_HFXO
/**
* @brief Initialization parameters for the external high frequency oscillator
*/
static const CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;
#elif (defined CONFIG_CMU_HFCLK_LFXO)
/**
* @brief Initialization parameters for the external low frequency oscillator
*/
static const CMU_LFXOInit_TypeDef lfxoInit = CMU_LFXOINIT_DEFAULT;
#endif
/**
* @brief Initialize the system clock
*
* @return N/A
*
*/
static ALWAYS_INLINE void clkInit(void)
{
#ifdef CONFIG_CMU_HFCLK_HFXO
if (CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_HFXO) {
CMU_HFXOInit(&hfxoInit);
CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
}
SystemHFXOClockSet(CONFIG_CMU_HFXO_FREQ);
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
#elif (defined CONFIG_CMU_HFCLK_LFXO)
if (CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_LFXO) {
CMU_LFXOInit(&lfxoInit);
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_LFXO);
}
SystemLFXOClockSet(CONFIG_CMU_LFXO_FREQ);
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
#elif (defined CONFIG_CMU_HFCLK_HFRCO)
/*
* This is the default clock, the controller starts with, so nothing to
* do here.
*/
#else
#error "Unsupported clock source for HFCLK selected"
#endif
/* Enable the High Frequency Peripheral Clock */
CMU_ClockEnable(cmuClock_HFPER, true);
#ifdef CONFIG_GPIO_GECKO
CMU_ClockEnable(cmuClock_GPIO, true);
#endif
}
/**
* @brief Perform basic hardware initialization
*
* Initialize the interrupt controller device drivers.
* Also initialize the timer device driver, if required.
*
* @return 0
*/
static int silabs_efr32fg1p_init(struct device *arg)
{
ARG_UNUSED(arg);
unsigned int oldLevel; /* old interrupt lock level */
/* disable interrupts */
oldLevel = irq_lock();
/* handle chip errata */
CHIP_Init();
_ClearFaults();
/* Initialize system clock according to CONFIG_CMU settings */
clkInit();
/*
* install default handler that simply resets the CPU
* if configured in the kernel, NOP otherwise
*/
NMI_INIT();
/* restore interrupt state */
irq_unlock(oldLevel);
return 0;
}
SYS_INIT(silabs_efr32fg1p_init, PRE_KERNEL_1, 0);