/** * \brief Configure PLL clock by giving MUL and DIV. * Disable PLL when 'mul' set to 0. * * \param mul PLL multiplier factor. * \param div PLL divider factor. */ extern void PMC_SetPllClock(uint32_t mul, uint32_t div) { if (mul != 0) { /* Init PLL speed */ PMC->CKGR_PLLR = CKGR_PLLR_STUCKTO1 | CKGR_PLLR_PLLCOUNT(PmcPllCnt) | CKGR_PLLR_MUL(mul - 1) | CKGR_PLLR_DIV(div); /* Wait for PLL stabilization */ while( !(PMC->PMC_SR & PMC_SR_LOCK) ); } else { PMC->CKGR_PLLR = CKGR_PLLR_STUCKTO1; /* disable PLL A */ } }
/* * Try to evaluate the correct divider and multiplier value depending * on the desired CPU frequency. * * We try all combinations in a certain range of divider and multiplier * values. Start with higher multipliers and divisors, generally better. */ INLINE uint32_t evaluate_pll(void) { int mul, div, best_mul, best_div; int best_delta = CPU_FREQ; int freq = 0; for (mul = 13; mul > 0; mul--) { for (div = 24; div > 0; div--) { freq = BOARDOSC_FREQ / div * (1 + mul); if (ABS((int)CPU_FREQ - freq) < best_delta) { best_delta = ABS((int)CPU_FREQ - freq); best_mul = mul; best_div = div; } } } return CKGR_PLLR_DIV(best_div) | CKGR_PLLR_MUL(best_mul); }
/* * Try to evaluate the correct divider and multiplier value depending * on the desired CPU frequency. * * We try all combinations in a certain range of divider and multiplier * values. The range can change, with better match with "strange" * frequencies, but boot time will be longer. * * Limits for SAM3N: divider [1,255], multiplier [1,2047]. */ INLINE uint32_t evaluate_pll(void) { int mul, div, best_mul, best_div; int best_delta = CPU_FREQ; int freq = 0; for (mul = 1; mul <= 8; mul++) { for (div = 1; div <= 24; div++) { freq = BOARDOSC_FREQ / div * (1 + mul); if (ABS((int)CPU_FREQ - freq) < best_delta) { best_delta = ABS((int)CPU_FREQ - freq); best_mul = mul; best_div = div; } } } // Bit 29 must always be set to 1 return CKGR_PLLR_DIV(best_div) | CKGR_PLLR_MUL(best_mul) | BV(29); }
INLINE uint32_t evaluate_pll(void) { return CKGR_PLLR_MUL(CPU_FREQ / BOARDOSC_FREQ * 2 - 1) | CKGR_PLLR_DIV(2); }