diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc index cc65f3bf140..a7bae5aafb0 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc @@ -1,6 +1,6 @@ # LPC LPC55XXX Series -# Copyright (c) 2019, NXP +# Copyright 2019, 2023 NXP # SPDX-License-Identifier: Apache-2.0 choice @@ -120,6 +120,14 @@ config SOC_PART_NUMBER_LPC55XXX config INIT_PLL0 bool "Initialize PLL0" +config INIT_PLL1 + bool "Initialize PLL1" + default "y" + depends on !SOC_LPC55S06 + help + In the LPC55XXX Family, this is currently being used to set the + core clock value at it's highest frequency which clocks at 150MHz. + config SECOND_CORE_MCUX bool "LPC55xxx's second core" depends on HAS_MCUX diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index 45c51d18424..c297553669c 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -35,6 +35,13 @@ #include #endif +/* System clock frequency */ +extern uint32_t SystemCoreClock; + +/*Should be in the range of 12MHz to 32MHz */ +static uint32_t ExternalClockFrequency; + + #define CTIMER_CLOCK_SOURCE(node_id) \ TO_CTIMER_CLOCK_SOURCE(DT_CLOCKS_CELL(node_id, name), DT_PROP(node_id, clk_source)) #define TO_CTIMER_CLOCK_SOURCE(inst, val) TO_CLOCK_ATTACH_ID(inst, val) @@ -44,13 +51,25 @@ #ifdef CONFIG_INIT_PLL0 const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(2U) | - SYSCON_PLL0CTRL_SELP(31U), + SYSCON_PLL0CTRL_SELP(31U), .pllndec = SYSCON_PLL0NDEC_NDIV(125U), .pllpdec = SYSCON_PLL0PDEC_PDIV(8U), .pllsscg = {0x0U, (SYSCON_PLL0SSCG1_MDIV_EXT(3072U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 24576000U, - .flags = PLL_SETUPFLAG_WAITLOCK} -; + .flags = PLL_SETUPFLAG_WAITLOCK +}; +#endif + +#ifdef CONFIG_INIT_PLL1 +const pll_setup_t pll1Setup = { + .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(53U) | + SYSCON_PLL1CTRL_SELP(31U), + .pllndec = SYSCON_PLL1NDEC_NDIV(8U), + .pllpdec = SYSCON_PLL1PDEC_PDIV(1U), + .pllmdec = SYSCON_PLL1MDEC_MDIV(150U), + .pllRate = 150000000U, + .flags = PLL_SETUPFLAG_WAITLOCK +}; #endif /** @@ -61,6 +80,7 @@ const pll_setup_t pll0Setup = { static ALWAYS_INLINE void clock_init(void) { + ExternalClockFrequency = 0; #if defined(CONFIG_SOC_LPC55S36) /* Power Management Controller initialization */ @@ -70,50 +90,91 @@ static ALWAYS_INLINE void clock_init(void) #if defined(CONFIG_SOC_LPC55S06) || defined(CONFIG_SOC_LPC55S16) || \ defined(CONFIG_SOC_LPC55S28) || defined(CONFIG_SOC_LPC55S36) || \ defined(CONFIG_SOC_LPC55S69_CPU0) - /*!< Set up the clock sources */ - /*!< Configure FRO192M */ - /*!< Ensure FRO is on */ + /* Set up the clock sources */ + /* Configure FRO192M */ + /* Ensure FRO is on */ POWER_DisablePD(kPDRUNCFG_PD_FRO192M); - /*!< Set up FRO to the 12 MHz, just for sure */ + /* Set up FRO to the 12 MHz, to ensure we can change the clock freq */ CLOCK_SetupFROClocking(12000000U); - /*!< Switch to FRO 12MHz first to ensure we can change the clock */ + /* Switch to FRO 12MHz first to ensure we can change the clock */ CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); - /* Enable FRO HF(96MHz) output */ - CLOCK_SetupFROClocking(96000000U); - -#ifdef CONFIG_INIT_PLL0 - /*!< Ensure XTAL16M is on */ - PMC->PDRUNCFGCLR0 |= PMC_PDRUNCFG0_PDEN_XTAL32M_MASK; - PMC->PDRUNCFGCLR0 |= PMC_PDRUNCFG0_PDEN_LDOXO32M_MASK; - - /*!< Ensure CLK_IN is on */ + /* Ensure CLK_IN is on */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; - /*!< Switch PLL0 clock source selector to XTAL16M */ - CLOCK_AttachClk(kEXT_CLK_to_PLL0); - - /*!< Configure PLL to the desired values */ - CLOCK_SetPLL0Freq(&pll0Setup); - - CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); - CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 1U, false); + /* Setting the Core Clock to either 96MHz or in the case of using PLL, 150MHz */ +#if defined(CONFIG_SOC_LPC55S06) || !defined(CONFIG_INIT_PLL1) + SystemCoreClock = 96000000U; +#else + SystemCoreClock = 150000000U; #endif + + /* These functions must be called before increasing to a higher frequency + * Additionally, CONFIG_TRUSTED_EXECUTION_NONSECURE is being used + * since the non-secure SOCs should not have access to the flash + * as this will cause a secure fault to occur + */ #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) + /* Set Voltage for one of the fastest clock outputs: System clock output */ + POWER_SetVoltageForFreq(SystemCoreClock); /*!< Set FLASH wait states for core */ - CLOCK_SetFLASHAccessCyclesForFreq(96000000U); + CLOCK_SetFLASHAccessCyclesForFreq(SystemCoreClock); +#endif /* !CONFIG_TRUSTED_EXECUTION_NONSECURE */ + + +#if defined(CONFIG_INIT_PLL0) || defined(CONFIG_INIT_PLL1) + /* Configure XTAL32M */ + ExternalClockFrequency = 16000000U; + CLOCK_SetupExtClocking(ExternalClockFrequency); #endif - /*!< Set up dividers */ - CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); +#if defined(CONFIG_SOC_LPC55S06) || !defined(CONFIG_INIT_PLL1) + /* Enable FRO HF(SystemCoreClock) output (Default expected value 96MHz) */ + CLOCK_SetupFROClocking(SystemCoreClock); - /*!< Set up clock selectors - Attach clocks to the peripheries */ + /* Switch MAIN_CLK to FRO_HF */ CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); +#else + /* Switch PLL1 clock source selector to XTAL32M */ + CLOCK_AttachClk(kEXT_CLK_to_PLL1); + + /* Ensure PLL1 is on */ + POWER_DisablePD(kPDRUNCFG_PD_PLL1); + + /* Configure PLL to the desired values */ + CLOCK_SetPLL1Freq(&pll1Setup); + + /* Switch MAIN_CLK to FRO_HF */ + CLOCK_AttachClk(kPLL1_to_MAIN_CLK); + +#endif /* CONFIG_SOC_LPC55S06 || !CONFIG_INIT_PLL1 */ + + +#ifdef CONFIG_INIT_PLL0 + /* Switch PLL0 clock source selector to XTAL32M */ + CLOCK_AttachClk(kEXT_CLK_to_PLL0); + + /* Configure PLL to the desired values */ + CLOCK_SetPLL0Freq(&pll0Setup); + +#if defined(CONFIG_SOC_LPC55S36) + CLOCK_SetClkDiv(kCLOCK_DivPllClk, 0U, true); + CLOCK_SetClkDiv(kCLOCK_DivPllClk, 1U, false); +#else + CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); + CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 1U, false); +#endif /* CONFIG_SOC_LPC55S36 */ +#endif /* CONFIG_INIT_PLL0 */ + + + /* Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); + /* Enables the clock for the I/O controller.: Enable Clock. */ - CLOCK_EnableClock(kCLOCK_Iocon); + CLOCK_EnableClock(kCLOCK_Iocon); #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm2), nxp_lpc_usart, okay) #if defined(CONFIG_SOC_LPC55S36) @@ -250,11 +311,11 @@ DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) #if defined(CONFIG_SOC_LPC55S36) && defined(CONFIG_PWM) /* Set the Submodule Clocks for FlexPWM */ SYSCON->PWM0SUBCTL |= - (SYSCON_PWM0SUBCTL_CLK0_EN_MASK | SYSCON_PWM0SUBCTL_CLK1_EN_MASK | - SYSCON_PWM0SUBCTL_CLK2_EN_MASK); + (SYSCON_PWM0SUBCTL_CLK0_EN_MASK | SYSCON_PWM0SUBCTL_CLK1_EN_MASK | + SYSCON_PWM0SUBCTL_CLK2_EN_MASK); SYSCON->PWM1SUBCTL |= - (SYSCON_PWM1SUBCTL_CLK0_EN_MASK | SYSCON_PWM1SUBCTL_CLK1_EN_MASK | - SYSCON_PWM1SUBCTL_CLK2_EN_MASK); + (SYSCON_PWM1SUBCTL_CLK0_EN_MASK | SYSCON_PWM1SUBCTL_CLK1_EN_MASK | + SYSCON_PWM1SUBCTL_CLK2_EN_MASK); #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(adc0), nxp_lpc_lpadc, okay) @@ -322,7 +383,7 @@ void z_arm_platform_init(void) * SystemInit unconditionally enables the trace clock. * Disable the trace clock unless SWO is used */ - SYSCON->TRACECLKDIV = 0x4000000; + SYSCON->TRACECLKDIV = 0x4000000; #endif }