17#ifndef FSL_COMPONENT_ID
18#define FSL_COMPONENT_ID "platform.drivers.clock"
21#define SCG_SIRC_LOW_RANGE_FREQ 2000000U
22#define SCG_SIRC_HIGH_RANGE_FREQ 8000000U
24#define SCG_FIRC_FREQ0 48000000U
25#define SCG_FIRC_FREQ1 52000000U
26#define SCG_FIRC_FREQ2 56000000U
27#define SCG_FIRC_FREQ3 60000000U
33#define SCG_SPLL_PREDIV_BASE_VALUE 1U
39#define SCG_SPLL_MULT_BASE_VALUE 16U
41#define SCG_SPLL_PREDIV_MAX_VALUE 7U
42#define SCG_SPLL_MULT_MAX_VALUE 31U
48#define SCG_SPLL_REF_MIN 8000000U
49#define SCG_SPLL_REF_MAX 32000000U
51#define SCG_CSR_SCS_VAL ((SCG->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT)
52#define SCG_SOSCDIV_SOSCDIV1_VAL ((SCG->SOSCDIV & SCG_SOSCDIV_SOSCDIV1_MASK) >> SCG_SOSCDIV_SOSCDIV1_SHIFT)
53#define SCG_SOSCDIV_SOSCDIV2_VAL ((SCG->SOSCDIV & SCG_SOSCDIV_SOSCDIV2_MASK) >> SCG_SOSCDIV_SOSCDIV2_SHIFT)
54#define SCG_SIRCDIV_SIRCDIV1_VAL ((SCG->SIRCDIV & SCG_SIRCDIV_SIRCDIV1_MASK) >> SCG_SIRCDIV_SIRCDIV1_SHIFT)
55#define SCG_SIRCDIV_SIRCDIV2_VAL ((SCG->SIRCDIV & SCG_SIRCDIV_SIRCDIV2_MASK) >> SCG_SIRCDIV_SIRCDIV2_SHIFT)
56#define SCG_FIRCDIV_FIRCDIV1_VAL ((SCG->FIRCDIV & SCG_FIRCDIV_FIRCDIV1_MASK) >> SCG_FIRCDIV_FIRCDIV1_SHIFT)
57#define SCG_FIRCDIV_FIRCDIV2_VAL ((SCG->FIRCDIV & SCG_FIRCDIV_FIRCDIV2_MASK) >> SCG_FIRCDIV_FIRCDIV2_SHIFT)
59#define SCG_SPLLDIV_SPLLDIV1_VAL ((SCG->SPLLDIV & SCG_SPLLDIV_SPLLDIV1_MASK) >> SCG_SPLLDIV_SPLLDIV1_SHIFT)
60#define SCG_SPLLDIV_SPLLDIV2_VAL ((SCG->SPLLDIV & SCG_SPLLDIV_SPLLDIV2_MASK) >> SCG_SPLLDIV_SPLLDIV2_SHIFT)
62#define SCG_SIRCCFG_RANGE_VAL ((SCG->SIRCCFG & SCG_SIRCCFG_RANGE_MASK) >> SCG_SIRCCFG_RANGE_SHIFT)
63#define SCG_FIRCCFG_RANGE_VAL ((SCG->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT)
65#define SCG_SPLLCFG_PREDIV_VAL ((SCG->SPLLCFG & SCG_SPLLCFG_PREDIV_MASK) >> SCG_SPLLCFG_PREDIV_SHIFT)
66#define SCG_SPLLCFG_MULT_VAL ((SCG->SPLLCFG & SCG_SPLLCFG_MULT_MASK) >> SCG_SPLLCFG_MULT_SHIFT)
68#define PCC_PCS_VAL(reg) (((reg) & PCC_CLKCFG_PCS_MASK) >> PCC_CLKCFG_PCS_SHIFT)
106 if (SCG->SOSCCSR & SCG_SOSCCSR_SOSCEN_MASK)
252 uint32_t reg = (*(
volatile uint32_t *)name);
257 assert(reg & PCC_CLKCFG_PR_MASK);
269 switch (PCC_PCS_VAL(reg))
300 assert(OSC32 == base);
305 base->CR = (uint8_t)mode;
307 if (mode & OSC32_CR_ROSCEREFS_MASK)
310 while (!(base->CR & OSC32_CR_ROSCSTB_MASK))
324 assert(OSC32 == base);
347 switch (sysClkConfig.
src)
366 freq /= (sysClkConfig.
divCore + 1U);
370 freq /= (sysClkConfig.
divSlow + 1U);
374 freq /= (sysClkConfig.
divBus + 1U);
407 if ((
config->freq >= 32768U) && (
config->freq <= 40000U))
411 else if ((
config->freq >= 1000000U) && (
config->freq <= 8000000U))
415 else if ((
config->freq >= 8000000U) && (
config->freq <= 32000000U))
435 SCG->SOSCDIV = SCG_SOSCDIV_SOSCDIV1(
config->div1) | SCG_SOSCDIV_SOSCDIV2(
config->div2);
438 SCG->SOSCCFG =
config->workMode | SCG_SOSCCFG_RANGE(range);
442 tmp8 =
config->enableMode;
443 tmp8 |= SCG_SOSCCSR_SOSCEN_MASK;
447 while (!(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK))
452 SCG->SOSCCSR |= (uint32_t)
config->monitorMode;
470 uint32_t reg = SCG->SOSCCSR;
473 if (reg & SCG_SOSCCSR_SOSCSEL_MASK)
479 if (reg & SCG_SOSCCSR_LK_MASK)
484 SCG->SOSCCSR = SCG_SOSCCSR_SOSCERR_MASK;
496 if (SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK)
517 uint32_t divider = 0U;
525 divider = SCG_SOSCDIV_SOSCDIV2_VAL;
528 divider = SCG_SOSCDIV_SOSCDIV1_VAL;
536 return oscFreq >> (divider - 1U);
574 SCG->SIRCDIV = SCG_SIRCDIV_SIRCDIV1(
config->div1) | SCG_SIRCDIV_SIRCDIV2(
config->div2);
577 SCG->SIRCCFG = SCG_SIRCCFG_RANGE(
config->range);
580 SCG->SIRCCSR = SCG_SIRCCSR_SIRCEN_MASK |
config->enableMode;
583 while (!(SCG->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK))
603 uint32_t reg = SCG->SIRCCSR;
606 if (reg & SCG_SIRCCSR_SIRCSEL_MASK)
612 if (reg & SCG_SIRCCSR_LK_MASK)
629 static const uint32_t sircFreq[] = {SCG_SIRC_LOW_RANGE_FREQ, SCG_SIRC_HIGH_RANGE_FREQ};
631 if (SCG->SIRCCSR & SCG_SIRCCSR_SIRCVLD_MASK)
633 return sircFreq[SCG_SIRCCFG_RANGE_VAL];
650 uint32_t divider = 0U;
658 divider = SCG_SIRCDIV_SIRCDIV2_VAL;
661 divider = SCG_SIRCDIV_SIRCDIV1_VAL;
669 return sircFreq >> (divider - 1U);
706 SCG->FIRCDIV = SCG_FIRCDIV_FIRCDIV1(
config->div1) | SCG_FIRCDIV_FIRCDIV2(
config->div2);
709 SCG->FIRCCFG = SCG_FIRCCFG_RANGE(
config->range);
715 SCG_FIRCTCFG_TRIMDIV(
config->trimConfig->trimDiv) | SCG_FIRCTCFG_TRIMSRC(
config->trimConfig->trimSrc);
720 SCG->FIRCSTAT = SCG_FIRCSTAT_TRIMCOAR(
config->trimConfig->trimCoar) |
721 SCG_FIRCSTAT_TRIMFINE(
config->trimConfig->trimFine);
725 SCG->FIRCCSR =
config->trimConfig->trimMode;
727 if (SCG->FIRCCSR & SCG_FIRCCSR_FIRCERR_MASK)
734 SCG->FIRCCSR |= (SCG_FIRCCSR_FIRCEN_MASK |
config->enableMode);
737 while (!(SCG->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK))
757 uint32_t reg = SCG->FIRCCSR;
760 if (reg & SCG_FIRCCSR_FIRCSEL_MASK)
766 if (reg & SCG_FIRCCSR_LK_MASK)
771 SCG->FIRCCSR = SCG_FIRCCSR_FIRCERR_MASK;
783 static const uint32_t fircFreq[] = {
784 SCG_FIRC_FREQ0, SCG_FIRC_FREQ1, SCG_FIRC_FREQ2, SCG_FIRC_FREQ3,
787 if (SCG->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK)
789 return fircFreq[SCG_FIRCCFG_RANGE_VAL];
806 uint32_t divider = 0U;
814 divider = SCG_FIRCDIV_FIRCDIV2_VAL;
817 divider = SCG_FIRCDIV_FIRCDIV1_VAL;
825 return fircFreq >> (divider - 1U);
856 uint32_t ret_freq = 0U;
857 uint32_t diff = 0xFFFFFFFFU;
874 if ((refFreq < SCG_SPLL_REF_MIN) ||
875 (refFreq > (SCG_SPLL_REF_MAX * (SCG_SPLL_PREDIV_MAX_VALUE + SCG_SPLL_PREDIV_BASE_VALUE))))
881 prediv_max = refFreq / SCG_SPLL_REF_MIN;
882 prediv_min = (refFreq + SCG_SPLL_REF_MAX - 1U) / SCG_SPLL_REF_MAX;
887 for (prediv_cur = prediv_max; prediv_cur >= prediv_min; prediv_cur--)
895 ref_div = refFreq / prediv_cur;
897 mult_cur = desireFreq / ref_div;
899 if ((mult_cur < SCG_SPLL_MULT_BASE_VALUE - 1U) ||
900 (mult_cur > SCG_SPLL_MULT_BASE_VALUE + SCG_SPLL_MULT_MAX_VALUE))
906 ret_freq = mult_cur * ref_div;
908 if (mult_cur >= SCG_SPLL_MULT_BASE_VALUE)
910 if (ret_freq == desireFreq)
912 *prediv = prediv_cur - SCG_SPLL_PREDIV_BASE_VALUE;
913 *mult = mult_cur - SCG_SPLL_MULT_BASE_VALUE;
914 return ret_freq / 2U;
916 if (diff > desireFreq - ret_freq)
918 diff = desireFreq - ret_freq;
919 ret_prediv = prediv_cur;
924 if (mult_cur <= (SCG_SPLL_MULT_BASE_VALUE + SCG_SPLL_MULT_MAX_VALUE))
927 if (diff > ret_freq - desireFreq)
929 diff = ret_freq - desireFreq;
930 ret_prediv = prediv_cur;
936 if (0xFFFFFFFFU != diff)
939 *prediv = ret_prediv - SCG_SPLL_PREDIV_BASE_VALUE;
940 *mult = ret_mult - SCG_SPLL_MULT_BASE_VALUE;
941 return ((refFreq / ret_prediv) * ret_mult) / 2;
1000 SCG->SPLLDIV = SCG_SPLLDIV_SPLLDIV1(
config->div1) | SCG_SPLLDIV_SPLLDIV2(
config->div2);
1004 SCG_SPLLCFG_SOURCE(
config->src) | SCG_SPLLCFG_PREDIV(
config->prediv) | SCG_SPLLCFG_MULT(
config->mult);
1007 SCG->SPLLCSR = SCG_SPLLCSR_SPLLEN_MASK |
config->enableMode;
1010 while (!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK))
1015 SCG->SPLLCSR |= (uint32_t)
config->monitorMode;
1033 uint32_t reg = SCG->SPLLCSR;
1036 if (reg & SCG_SPLLCSR_SPLLSEL_MASK)
1042 if (reg & SCG_SPLLCSR_LK_MASK)
1048 SCG->SPLLCSR = SCG_SPLLCSR_SPLLERR_MASK;
1057 if (SCG->SPLLCFG & SCG_SPLLCFG_SOURCE_MASK)
1068 freq /= (SCG_SPLLCFG_PREDIV_VAL + SCG_SPLL_PREDIV_BASE_VALUE);
1069 freq *= (SCG_SPLLCFG_MULT_VAL + SCG_SPLL_MULT_BASE_VALUE);
1084 if (SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK)
1105 uint32_t divider = 0U;
1113 divider = SCG_SPLLDIV_SPLLDIV2_VAL;
1116 divider = SCG_SPLLDIV_SPLLDIV1_VAL;
1124 return pllFreq >> (divider - 1U);
static constexpr persistent_config_s * config
static uint32_t CLOCK_GetSysPllCommonFreq(void)
Get the common System PLL frequency for both RAW SPLL output and SPLL PFD output.
enum _clock_ip_name clock_ip_name_t
Peripheral clock name difinition used for clock gate, clock source and clock divider setting....
uint32_t CLOCK_GetSysPllMultDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *mult, uint8_t *prediv)
Calculates the MULT and PREDIV for the PLL.
volatile uint32_t g_xtal32Freq
External XTAL32/EXTAL32 clock frequency.
uint32_t CLOCK_GetSysPllFreq(void)
Gets the SCG system PLL clock frequency.
uint32_t CLOCK_GetIpFreq(clock_ip_name_t name)
Gets the clock frequency for a specific IP module.
enum _clock_name clock_name_t
Clock name used to get clock frequency.
static void CLOCK_DisableClock(clock_ip_name_t name)
Disable the clock for specific IP.
void OSC32_Deinit(OSC32_Type *base)
Deinitializes OSC32.
uint32_t CLOCK_GetCoreSysClkFreq(void)
Get the core clock or system clock frequency.
uint32_t CLOCK_GetSysPllAsyncFreq(scg_async_clk_t type)
Gets the SCG asynchronous clock frequency from the system PLL.
enum _scg_sys_clk scg_sys_clk_t
SCG system clock type.
status_t CLOCK_DeinitFirc(void)
De-initializes the SCG fast IRC.
uint32_t CLOCK_GetSircFreq(void)
Gets the SCG SIRC clock frequency.
uint32_t CLOCK_GetFreq(clock_name_t clockName)
Gets the clock frequency for a specific clock name.
uint32_t CLOCK_GetFircFreq(void)
Gets the SCG FIRC clock frequency.
volatile uint32_t g_xtal0Freq
External XTAL0 (OSC0/SYSOSC) clock frequency.
enum _scg_async_clk scg_async_clk_t
SCG asynchronous clock type.
uint32_t CLOCK_GetErClkFreq(void)
Get the external reference clock frequency (ERCLK).
uint32_t CLOCK_GetSysClkFreq(scg_sys_clk_t type)
Gets the SCG system clock frequency.
status_t CLOCK_DeinitSysPll(void)
De-initializes the SCG system PLL.
static void CLOCK_GetCurSysClkConfig(scg_sys_clk_config_t *config)
Gets the system clock configuration in the current power mode.
uint32_t CLOCK_GetBusClkFreq(void)
Get the bus clock frequency.
uint32_t CLOCK_GetSircAsyncFreq(scg_async_clk_t type)
Gets the SCG asynchronous clock frequency from the SIRC.
uint32_t CLOCK_GetFlashClkFreq(void)
Get the flash clock frequency.
void OSC32_Init(OSC32_Type *base, osc32_mode_t mode)
Initializes OSC32.
uint32_t CLOCK_GetSysOscFreq(void)
Gets the SCG system OSC clock frequency (SYSOSC).
status_t CLOCK_DeinitSirc(void)
De-initializes the SCG slow IRC.
uint32_t CLOCK_GetOsc32kClkFreq(void)
Get the OSC 32K clock frequency (OSC32KCLK).
status_t CLOCK_InitSirc(const scg_sirc_config_t *config)
Initializes the SCG slow IRC clock.
status_t CLOCK_InitFirc(const scg_firc_config_t *config)
Initializes the SCG fast IRC clock.
status_t CLOCK_InitSysPll(const scg_spll_config_t *config)
Initializes the SCG system PLL.
uint32_t CLOCK_GetFircAsyncFreq(scg_async_clk_t type)
Gets the SCG asynchronous clock frequency from the FIRC.
status_t CLOCK_DeinitSysOsc(void)
De-initializes the SCG system OSC.
status_t CLOCK_InitSysOsc(const scg_sosc_config_t *config)
Initializes the SCG system OSC.
static void CLOCK_EnableClock(clock_ip_name_t name)
Enable the clock for specific IP.
uint32_t CLOCK_GetSysOscAsyncFreq(scg_async_clk_t type)
Gets the SCG asynchronous clock frequency from the system OSC.
enum _osc32_mode osc32_mode_t
OSC32 work mode.
@ kCLOCK_ScgSysOscAsyncDiv1Clk
@ kCLOCK_ScgSysPllAsyncDiv2Clk
@ kCLOCK_ScgSysOscAsyncDiv2Clk
@ kCLOCK_ScgFircAsyncDiv2Clk
@ kCLOCK_ScgSircAsyncDiv1Clk
@ kCLOCK_ScgSircAsyncDiv2Clk
@ kCLOCK_ScgFircAsyncDiv1Clk
@ kCLOCK_ScgSysPllAsyncDiv1Clk
@ kCLOCK_IpSrcSysPllAsync
@ kCLOCK_IpSrcSysOscAsync
int32_t status_t
Type used for all status and error return values.
@ kStatus_InvalidArgument
SCG fast IRC clock configuration.
SCG slow IRC clock configuration.
SCG system OSC configuration.
SCG system PLL configuration.
SCG system clock configuration.