in lib/nxp/drivers/fsl_clock.c [2526:2613]
void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq)
{
uint32_t cco_freq = input_freq * multiply_by;
uint32_t pdec = 1U;
uint32_t selr;
uint32_t seli;
uint32_t selp;
uint32_t mdec, ndec;
uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1);
while (cco_freq < 275000000U)
{
multiply_by <<= 1U; /* double value in each iteration */
pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
cco_freq = input_freq * multiply_by;
}
selr = 0U;
if (multiply_by < 60U)
{
seli = (multiply_by & 0x3cU) + 4U;
selp = (multiply_by >> 1U) + 1U;
}
else
{
selp = 31U;
if (multiply_by > 16384U)
{
seli = 1U;
}
else if (multiply_by > 8192U)
{
seli = 2U;
}
else if (multiply_by > 2048U)
{
seli = 4U;
}
else if (multiply_by >= 501U)
{
seli = 8U;
}
else
{
seli = 4U * (1024U / (multiply_by + 9U));
}
}
if (pdec > 1U)
{
directo = 0U; /* use post divider */
pdec = pdec / 2U; /* Account for minus 1 encoding */
/* Translate P value */
switch (pdec)
{
case 1U:
pdec = 0x62U; /* 1 * 2 */
break;
case 2U:
pdec = 0x42U; /* 2 * 2 */
break;
case 4U:
pdec = 0x02U; /* 4 * 2 */
break;
case 8U:
pdec = 0x0bU; /* 8 * 2 */
break;
case 16U:
pdec = 0x11U; /* 16 * 2 */
break;
case 32U:
pdec = 0x08U; /* 32 * 2 */
break;
default:
pdec = 0x08U;
break;
}
}
mdec = PLL_MDEC_VAL_SET(pllEncodeM(multiply_by));
ndec = 0x302U; /* pre divide by 1 (hardcoded) */
SYSCON->SYSPLLCTRL = directo | (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) |
(selp << SYSCON_SYSPLLCTRL_SELP_SHIFT);
SYSCON->SYSPLLPDEC = pdec | (1U << 7U); /* set Pdec value and assert preq */
SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */
SYSCON->SYSPLLMDEC = (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */
}