Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | /*
* Copyright (c) 2019 SEAL AG
*
* Based on NXP K6x soc.c, which is:
* Copyright (c) 2014-2015 Wind River Systems, Inc.
* Copyright (c) 2016, Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <fsl_common.h>
#include <fsl_clock.h>
#define PERIPH_CLK_PLLFLLSEL (1)
#define PERIPH_CLK_OSCERCLK (2)
#define PERIPH_CLK_MCGIRCLK (3)
#define RUNM_RUN (0)
#define RUNM_VLPR (2)
#define RUNM_HSRUN (3)
#define CLOCK_NODEID(clk) \
DT_CHILD(DT_INST(0, nxp_kinetis_sim), clk)
#define CLOCK_DIVIDER(clk) \
DT_PROP_OR(CLOCK_NODEID(clk), clock_div, 1) - 1
static const osc_config_t osc_config = {
.freq = CONFIG_OSC_XTAL0_FREQ,
.capLoad = 0,
#if defined(CONFIG_OSC_EXTERNAL)
.workMode = kOSC_ModeExt,
#elif defined(CONFIG_OSC_LOW_POWER)
.workMode = kOSC_ModeOscLowPower,
#elif defined(CONFIG_OSC_HIGH_GAIN)
.workMode = kOSC_ModeOscHighGain,
#else
#error "An oscillator mode must be defined"
#endif
.oscerConfig = {
.enableMode = kOSC_ErClkEnable,
#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && \
FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
.erclkDiv = 0U,
#endif
},
};
static const mcg_pll_config_t pll0_config = {
.enableMode = 0U,
.prdiv = CONFIG_MCG_PRDIV0,
.vdiv = CONFIG_MCG_VDIV0,
};
static const sim_clock_config_t sim_config = {
.pllFllSel = DT_PROP(DT_INST(0, nxp_kinetis_sim), pllfll_select),
.er32kSrc = DT_PROP(DT_INST(0, nxp_kinetis_sim), er32k_select),
.clkdiv1 = SIM_CLKDIV1_OUTDIV1(CLOCK_DIVIDER(core_clk)) |
SIM_CLKDIV1_OUTDIV2(CLOCK_DIVIDER(bus_clk)) |
SIM_CLKDIV1_OUTDIV3(CLOCK_DIVIDER(flexbus_clk)) |
SIM_CLKDIV1_OUTDIV4(CLOCK_DIVIDER(flash_clk)),
/* Divide PLL output frequency by 2 for peripherals */
.pllFllDiv = (1),
.pllFllFrac = (0),
};
static ALWAYS_INLINE void clk_init(void)
{
CLOCK_SetSimSafeDivs();
CLOCK_InitOsc0(&osc_config);
CLOCK_SetXtal0Freq(CONFIG_OSC_XTAL0_FREQ);
CLOCK_BootToPeeMode(kMCG_OscselOsc, kMCG_PllClkSelPll0, &pll0_config);
CLOCK_SetInternalRefClkConfig(kMCG_IrclkEnable, kMCG_IrcSlow,
CONFIG_MCG_FCRDIV);
CLOCK_SetSimConfig(&sim_config);
#if CONFIG_UART_MCUX_LPUART
CLOCK_SetLpuartClock(PERIPH_CLK_PLLFLLSEL);
#endif
#if CONFIG_USB_KINETIS
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, 120000000UL);
#endif
}
static int k8x_init(const struct device *arg)
{
ARG_UNUSED(arg);
unsigned int old_level; /* old interrupt lock level */
#if !defined(CONFIG_ARM_MPU)
uint32_t temp_reg;
#endif /* !CONFIG_ARM_MPU */
/* Disable interrupts */
old_level = irq_lock();
/* release I/O power hold to allow normal run state */
PMC->REGSC |= PMC_REGSC_ACKISO_MASK;
#if !defined(CONFIG_ARM_MPU)
/*
* Disable memory protection and clear slave port errors.
* Note that the K8x does not implement the optional ARMv7-M memory
* protection unit (MPU), specified by the architecture (PMSAv7), in the
* Cortex-M4 core. Instead, the processor includes its own MPU module.
*/
temp_reg = SYSMPU->CESR;
temp_reg &= ~SYSMPU_CESR_VLD_MASK;
temp_reg |= SYSMPU_CESR_SPERR_MASK;
SYSMPU->CESR = temp_reg;
#endif /* !CONFIG_ARM_MPU */
/* Initialize system clocks and PLL */
clk_init();
/*
* Install default handler that simply resets the CPU if
* configured in the kernel, NOP otherwise
*/
NMI_INIT();
/* Restore interrupt state */
irq_unlock(old_level);
return 0;
}
SYS_INIT(k8x_init, PRE_KERNEL_1, 0);
|