From cf425910eeba9117ea4d80f26e7f8d3569fb1f2d Mon Sep 17 00:00:00 2001 From: Aleksander Kaminski Date: Mon, 29 Jul 2024 17:03:23 +0200 Subject: [PATCH] mcxn94x: Enable PLL0 @150 MHz and use it as CPU clk JIRA: RTOS-881 --- hal/armv8m/mcx/n94x/n94x.c | 94 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/hal/armv8m/mcx/n94x/n94x.c b/hal/armv8m/mcx/n94x/n94x.c index 88822d12..e3d2c5b1 100644 --- a/hal/armv8m/mcx/n94x/n94x.c +++ b/hal/armv8m/mcx/n94x/n94x.c @@ -596,6 +596,82 @@ static void _mcxn94x_clockConfigOsc32khz(u8 extal, u8 cap, u8 gain) } +static void _mcxn94x_clockConfigExtClk(u32 freq) +{ + u8 range; + + if (freq < (20 * 1000 * 1000)) { + range = 0; + } + else if (freq < (30 * 1000 * 1000)) { + range = 1; + } + else if (freq < (50 * 1000 * 1000)) { + range = 2; + } + else { + range = 3; + } + + /* Clear errors if present */ + *(n94x_common.scg + scg_sosccsr) = (1 << 26); + + /* Set range and internal reference */ + *(n94x_common.scg + scg_sosccfg) = (range << 4) | (1 << 2); + + /* Unlock SOSCCSR */ + *(n94x_common.scg + scg_sosccsr) &= ~(1 << 23); + hal_cpuDataMemoryBarrier(); + + /* Enable clock and monitor */ + *(n94x_common.scg + scg_sosccsr) |= (1 << 17) | 1; + hal_cpuDataMemoryBarrier(); + + /* Wait for clock to stabilize */ + while ((*(n94x_common.scg + scg_sosccsr) & (1 << 24)) == 0) { + } +} + + +static void _mcxn94x_clockConfigPLL0(u8 source, u8 seli, u8 selp, u8 mdiv, u8 pdiv, u8 ndiv) +{ + /* Power off during config */ + *(n94x_common.scg + scg_apllcsr) &= ~((1 << 1) | 1); + hal_cpuDataMemoryBarrier(); + + /* Configure parameters */ + *(n94x_common.scg + scg_apllctrl) = ((source & 0x3) << 25) | ((selp & 0x1f) << 10) | ((seli & 0x3f) << 4); + *(n94x_common.scg + scg_apllndiv) = ndiv; + hal_cpuDataMemoryBarrier(); + *(n94x_common.scg + scg_apllndiv) = ndiv | (1u << 31); + *(n94x_common.scg + scg_apllpdiv) = pdiv; + hal_cpuDataMemoryBarrier(); + *(n94x_common.scg + scg_apllpdiv) = pdiv | (1u << 31); + *(n94x_common.scg + scg_apllmdiv) = mdiv; + hal_cpuDataMemoryBarrier(); + *(n94x_common.scg + scg_apllmdiv) = mdiv | (1u << 31); + hal_cpuDataMemoryBarrier(); + *(n94x_common.scg + scg_apllsscg0) = 0; + *(n94x_common.scg + scg_apllsscg1) = 0; + + /* Unlock scg_aplllock_cnfg */ + *(n94x_common.scg + scg_trimlock) = 0x5a5a0001; + hal_cpuDataMemoryBarrier(); + + /* Config lock time */ + *(n94x_common.scg + scg_aplllockcnfg) = (SOSC_FREQ / 2000) + 300; + hal_cpuDataMemoryBarrier(); + + /* Enable PLL0 */ + *(n94x_common.scg + scg_apllcsr) |= (1 << 1) | 1; + hal_cpuDataMemoryBarrier(); + + /* Wait for lock */ + while ((*(n94x_common.scg + scg_apllcsr) & (1 << 24)) == 0) { + } +} + + void _mcxn94x_init(void) { int i; @@ -658,4 +734,22 @@ void _mcxn94x_init(void) /* Enable 32 KHz oscillator */ /* TODO determine EXTAL_CAP_SEL, XTAL_CAP_SEL and COARSE_AMP_GAIN values */ _mcxn94x_clockConfigOsc32khz(ROSC_EXTALCAP_PF / 2, ROSC_CAP_PF / 2, ROSC_AMP_GAIN); + + /* Configure 24 MHz oscillator pins */ + _mcxn94x_portPinConfig(pctl_pin_p1_30, 0, MCX_PIN_FAST | MCX_PIN_INPUT_BUFFER_ENABLE); + _mcxn94x_portPinConfig(pctl_pin_p1_31, 0, MCX_PIN_FAST | MCX_PIN_INPUT_BUFFER_ENABLE); + + /* Enable oscillator */ + _mcxn94x_clockConfigExtClk(SOSC_FREQ); + + /* Enable PPL0 @150 MHz, SOSC source */ + _mcxn94x_clockConfigPLL0(0, 27, 13, 8, 1, 50); + + /* Select PLL0 as a main clock */ + *(n94x_common.scg + scg_rccr) = 5 << 24; + hal_cpuDataMemoryBarrier(); + + /* Set AHB clock divider to clk / 1 */ + *(n94x_common.syscon + syscon_ahbclkdiv) = 0; + hal_cpuDataMemoryBarrier(); }