1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #14896 from aabadie/pr/boards/hifive_clock_cleanup

boards/hifive*: improve clock configuration and initialization
This commit is contained in:
Leandro Lanzieri 2020-09-09 15:40:22 +02:00 committed by GitHub
commit 7d680046c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 74 deletions

View File

@ -33,22 +33,22 @@ extern "C" {
#ifndef CONFIG_USE_CLOCK_HFXOSC_PLL
#if IS_ACTIVE(CONFIG_USE_CLOCK_HFXOSC) || IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC_PLL) || \
IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC)
#define CONFIG_USE_CLOCK_HFXOSC_PLL (0)
#define CONFIG_USE_CLOCK_HFXOSC_PLL 0
#else
#define CONFIG_USE_CLOCK_HFXOSC_PLL (1) /* Use PLL clocked by HFXOSC by default */
#define CONFIG_USE_CLOCK_HFXOSC_PLL 1 /* Use PLL clocked by HFXOSC by default */
#endif
#endif /* CONFIG_USE_CLOCK_HFXOSC_PLL */
#ifndef CONFIG_USE_CLOCK_HFXOSC
#define CONFIG_USE_CLOCK_HFXOSC (0)
#define CONFIG_USE_CLOCK_HFXOSC 0
#endif /* CONFIG_USE_CLOCK_HFXOSC */
#ifndef CONFIG_USE_CLOCK_HFROSC_PLL
#define CONFIG_USE_CLOCK_HFROSC_PLL (0)
#define CONFIG_USE_CLOCK_HFROSC_PLL 0
#endif /* CONFIG_USE_CLOCK_HFROSC_PLL */
#ifndef CONFIG_USE_CLOCK_HFROSC
#define CONFIG_USE_CLOCK_HFROSC (0)
#define CONFIG_USE_CLOCK_HFROSC 0
#endif /* CONFIG_USE_CLOCK_HFROSC */
#if CONFIG_USE_CLOCK_HFXOSC_PLL && \
@ -71,7 +71,6 @@ extern "C" {
#error "Cannot use HFROSC with other clock configurations"
#endif
#if CONFIG_USE_CLOCK_HFXOSC_PLL
#define CONFIG_CLOCK_PLL_R (1) /* Divide input clock by 2, mandatory with HFXOSC */
#ifndef CONFIG_CLOCK_PLL_F
#define CONFIG_CLOCK_PLL_F (39) /* Multiply REFR by 80, e.g 2 * (39 + 1) */
@ -79,46 +78,43 @@ extern "C" {
#ifndef CONFIG_CLOCK_PLL_Q
#define CONFIG_CLOCK_PLL_Q (1) /* Divide VCO by 2, e.g 2^1 */
#endif
#define CLOCK_PLL_INPUT_CLOCK (16000000UL)
#if CONFIG_USE_CLOCK_HFXOSC_PLL
#define CLOCK_PLL_INPUT_CLOCK MHZ(16)
#define CLOCK_PLL_REFR (CLOCK_PLL_INPUT_CLOCK / (CONFIG_CLOCK_PLL_R + 1))
#define CLOCK_PLL_VCO (CLOCK_PLL_REFR * (2 * (CONFIG_CLOCK_PLL_F + 1)))
#define CLOCK_PLL_OUT (CLOCK_PLL_VCO / (1 << CONFIG_CLOCK_PLL_Q))
#define CLOCK_CORECLOCK (CLOCK_PLL_OUT) /* 320000000Hz with the values used above */
/* Check PLL settings */
#if CLOCK_PLL_REFR != 8000000
#if CLOCK_PLL_REFR != MHZ(8)
#error "Only R=2 can be used when using HFXOSC"
#endif
#if (CLOCK_PLL_VCO < 384000000) || (CLOCK_PLL_VCO > 768000000)
#if (CLOCK_PLL_VCO < MHZ(384)) || (CLOCK_PLL_VCO > MHZ(768))
#error "VCO frequency must be in the range [384MHz - 768MHz], check the CLOCK_PLL_F value"
#endif
#if (CLOCK_PLL_OUT < 48000000) || (CLOCK_PLL_OUT > 384000000)
#if (CLOCK_PLL_OUT < MHZ(48)) || (CLOCK_PLL_OUT > MHZ(384))
#error "PLL output frequency must be in the range [48MHz - 384MHz], check the CLOCK_PLL_Q value"
#endif
#elif CONFIG_USE_CLOCK_HFXOSC
#define CLOCK_CORECLOCK (16000000UL)
#define CLOCK_CORECLOCK MHZ(16)
#endif
/*
When using HFROSC input clock, the core clock cannot be computed from settings,
call cpu_freq() to get the configured CPU frequency.
*/
#elif CONFIG_USE_CLOCK_HFROSC_PLL
#ifndef CONFIG_CLOCK_DESIRED_FREQUENCY
#define CONFIG_CLOCK_DESIRED_FREQUENCY (320000000UL)
#define CONFIG_CLOCK_DESIRED_FREQUENCY MHZ(320)
#endif
#elif CONFIG_USE_CLOCK_HFROSC
#ifndef CONFIG_CLOCK_HFROSC_TRIM
#define CONFIG_CLOCK_HFROSC_TRIM (6) /* ~72000000Hz input freq */
#endif
#ifndef CONFIG_CLOCK_HFROSC_DIV
#define CONFIG_CLOCK_HFROSC_DIV (1) /* Divide by 2 */
#endif
#else
#error "Invalid clock configuration"
#endif
/** @} */
/**

View File

@ -34,22 +34,22 @@ extern "C" {
#ifndef CONFIG_USE_CLOCK_HFXOSC_PLL
#if IS_ACTIVE(CONFIG_USE_CLOCK_HFXOSC) || IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC_PLL) || \
IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC)
#define CONFIG_USE_CLOCK_HFXOSC_PLL (0)
#define CONFIG_USE_CLOCK_HFXOSC_PLL 0
#else
#define CONFIG_USE_CLOCK_HFXOSC_PLL (1) /* Use PLL clocked by HFXOSC by default */
#define CONFIG_USE_CLOCK_HFXOSC_PLL 1 /* Use PLL clocked by HFXOSC by default */
#endif
#endif /* CONFIG_USE_CLOCK_HFXOSC_PLL */
#ifndef CONFIG_USE_CLOCK_HFXOSC
#define CONFIG_USE_CLOCK_HFXOSC (0)
#define CONFIG_USE_CLOCK_HFXOSC 0
#endif /* CONFIG_USE_CLOCK_HFXOSC */
#ifndef CONFIG_USE_CLOCK_HFROSC_PLL
#define CONFIG_USE_CLOCK_HFROSC_PLL (0)
#define CONFIG_USE_CLOCK_HFROSC_PLL 0
#endif /* CONFIG_USE_CLOCK_HFROSC_PLL */
#ifndef CONFIG_USE_CLOCK_HFROSC
#define CONFIG_USE_CLOCK_HFROSC (0)
#define CONFIG_USE_CLOCK_HFROSC 0
#endif /* CONFIG_USE_CLOCK_HFROSC */
#if CONFIG_USE_CLOCK_HFXOSC_PLL && \
@ -72,7 +72,6 @@ extern "C" {
#error "Cannot use HFROSC with other clock configurations"
#endif
#if CONFIG_USE_CLOCK_HFXOSC_PLL
#define CONFIG_CLOCK_PLL_R (1) /* Divide input clock by 2, mandatory with HFXOSC */
#ifndef CONFIG_CLOCK_PLL_F
#define CONFIG_CLOCK_PLL_F (39) /* Multiply REFR by 80, e.g 2 * (39 + 1) */
@ -80,46 +79,43 @@ extern "C" {
#ifndef CONFIG_CLOCK_PLL_Q
#define CONFIG_CLOCK_PLL_Q (1) /* Divide VCO by 2, e.g 2^1 */
#endif
#define CLOCK_PLL_INPUT_CLOCK (16000000UL)
#if CONFIG_USE_CLOCK_HFXOSC_PLL
#define CLOCK_PLL_INPUT_CLOCK MHZ(16)
#define CLOCK_PLL_REFR (CLOCK_PLL_INPUT_CLOCK / (CONFIG_CLOCK_PLL_R + 1))
#define CLOCK_PLL_VCO (CLOCK_PLL_REFR * (2 * (CONFIG_CLOCK_PLL_F + 1)))
#define CLOCK_PLL_OUT (CLOCK_PLL_VCO / (1 << CONFIG_CLOCK_PLL_Q))
#define CLOCK_CORECLOCK (CLOCK_PLL_OUT) /* 320000000Hz with the values used above */
/* Check PLL settings */
#if CLOCK_PLL_REFR != 8000000
#if CLOCK_PLL_REFR != MHZ(8)
#error "Only R=2 can be used when using HFXOSC"
#endif
#if (CLOCK_PLL_VCO < 384000000) || (CLOCK_PLL_VCO > 768000000)
#if (CLOCK_PLL_VCO < MHZ(384)) || (CLOCK_PLL_VCO > MHZ(768))
#error "VCO frequency must be in the range [384MHz - 768MHz], check the CLOCK_PLL_F value"
#endif
#if (CLOCK_PLL_OUT < 48000000) || (CLOCK_PLL_OUT > 384000000)
#if (CLOCK_PLL_OUT < MHZ(48)) || (CLOCK_PLL_OUT > MHZ(384))
#error "PLL output frequency must be in the range [48MHz - 384MHz], check the CLOCK_PLL_Q value"
#endif
#elif CONFIG_USE_CLOCK_HFXOSC
#define CLOCK_CORECLOCK (16000000UL)
#define CLOCK_CORECLOCK MHZ(16)
#endif
/*
When using HFROSC input clock, the core clock cannot be computed from settings,
call cpu_freq() to get the configured CPU frequency.
*/
#elif CONFIG_USE_CLOCK_HFROSC_PLL
#ifndef CONFIG_CLOCK_DESIRED_FREQUENCY
#define CONFIG_CLOCK_DESIRED_FREQUENCY (320000000UL)
#define CONFIG_CLOCK_DESIRED_FREQUENCY MHZ(320)
#endif
#elif CONFIG_USE_CLOCK_HFROSC
#ifndef CONFIG_CLOCK_HFROSC_TRIM
#define CONFIG_CLOCK_HFROSC_TRIM (6) /* ~72000000Hz input freq */
#endif
#ifndef CONFIG_CLOCK_HFROSC_DIV
#define CONFIG_CLOCK_HFROSC_DIV (1) /* Divide by 2 */
#endif
#else
#error "Invalid clock configuration"
#endif
/** @} */
/**

View File

@ -22,7 +22,7 @@
#include "vendor/prci_driver.h"
#if !(CONFIG_USE_CLOCK_HFXOSC || CONFIG_USE_CLOCK_HFXOSC_PLL)
#if IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC) || IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC_PLL)
static uint32_t _cpu_frequency = 0;
#endif
@ -41,58 +41,59 @@ void clock_init(void)
PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(PLL_SEL_PLL);
}
#if CONFIG_USE_CLOCK_HFXOSC || CONFIG_USE_CLOCK_HFXOSC_PLL
/* Ensure HFXOSC is enabled */
PRCI_REG(PRCI_HFXOSCCFG) = XOSC_EN(1);
if (IS_ACTIVE(CONFIG_USE_CLOCK_HFXOSC) || IS_ACTIVE(CONFIG_USE_CLOCK_HFXOSC_PLL)) {
/* Ensure HFXOSC is enabled */
PRCI_REG(PRCI_HFXOSCCFG) = XOSC_EN(1);
/* Wait for HFXOSC to become ready */
while ((PRCI_REG(PRCI_HFXOSCCFG) & XOSC_RDY(1)) == 0);
/* Wait for HFXOSC to become ready */
while ((PRCI_REG(PRCI_HFXOSCCFG) & XOSC_RDY(1)) == 0);
/* Select HFXOSC as reference frequency and bypass PLL */
PRCI_REG(PRCI_PLLCFG) = PLL_REFSEL(PLL_REFSEL_HFXOSC) | PLL_BYPASS(1);
/* Select HFXOSC as reference frequency and bypass PLL */
PRCI_REG(PRCI_PLLCFG) = PLL_REFSEL(PLL_REFSEL_HFXOSC) | PLL_BYPASS(1);
#if CONFIG_USE_CLOCK_HFXOSC_PLL
/* Divide final output frequency by 1 */
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
if (IS_ACTIVE(CONFIG_USE_CLOCK_HFXOSC_PLL)) {
/* Divide final output frequency by 1 */
PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0));
/* Configure PLL */
PRCI_REG(PRCI_PLLCFG) |= PLL_R(CONFIG_CLOCK_PLL_R) | PLL_F(CONFIG_CLOCK_PLL_F) | PLL_Q(CONFIG_CLOCK_PLL_Q);
/* Configure PLL */
PRCI_REG(PRCI_PLLCFG) |= PLL_R(CONFIG_CLOCK_PLL_R) | PLL_F(CONFIG_CLOCK_PLL_F) | PLL_Q(CONFIG_CLOCK_PLL_Q);
/* Disable PLL Bypass */
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
/* Disable PLL Bypass */
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
/* Now it is safe to check for PLL Lock */
while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0);
#endif
/* Now it is safe to check for PLL Lock */
while ((PRCI_REG(PRCI_PLLCFG) & PLL_LOCK(1)) == 0);
}
/* Switch over to PLL Clock source */
PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(PLL_SEL_PLL);
/* Switch over to PLL Clock source */
PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(PLL_SEL_PLL);
/* Turn off the HFROSC */
PRCI_REG(PRCI_HFROSCCFG) &= ~ROSC_EN(1);
#elif CONFIG_USE_CLOCK_HFROSC_PLL
PRCI_set_hfrosctrim_for_f_cpu(CONFIG_CLOCK_DESIRED_FREQUENCY, PRCI_FREQ_UNDERSHOOT);
#else /* Clock HFROSC */
/* Disable Bypass */
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
/* Turn off the HFROSC */
PRCI_REG(PRCI_HFROSCCFG) &= ~ROSC_EN(1);
}
else if (IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC_PLL)) {
PRCI_set_hfrosctrim_for_f_cpu(CONFIG_CLOCK_DESIRED_FREQUENCY, PRCI_FREQ_UNDERSHOOT);
}
else { /* Clock HFROSC */
/* Disable Bypass */
PRCI_REG(PRCI_PLLCFG) &= ~PLL_BYPASS(1);
/* Configure trim and divider values of HFROSC */
PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(CONFIG_CLOCK_HFROSC_DIV) | ROSC_TRIM(CONFIG_CLOCK_HFROSC_TRIM) | ROSC_EN(1));
/* Configure trim and divider values of HFROSC */
PRCI_REG(PRCI_HFROSCCFG) = (ROSC_DIV(CONFIG_CLOCK_HFROSC_DIV) | ROSC_TRIM(CONFIG_CLOCK_HFROSC_TRIM) | ROSC_EN(1));
/* Wait for HFROSC to be ready */
while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0);
/* Wait for HFROSC to be ready */
while ((PRCI_REG(PRCI_HFROSCCFG) & ROSC_RDY(1)) == 0);
/* Don't use PLL clock source */
PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(PLL_SEL_PLL);
#endif
/* Don't use PLL clock source */
PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(PLL_SEL_PLL);
}
}
uint32_t cpu_freq(void)
{
#if CONFIG_USE_CLOCK_HFXOSC || CONFIG_USE_CLOCK_HFXOSC_PLL
return CLOCK_CORECLOCK;
#else /* Clock frequency with HFROSC cannot be determined precisely from
settings */
#if IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC) || IS_ACTIVE(CONFIG_USE_CLOCK_HFROSC_PLL)
/* Clock frequency with HFROSC cannot be determined precisely from
settings */
/* If not done already, estimate the CPU frequency */
if (_cpu_frequency == 0) {
/* Ignore the first run (for icache reasons) */
@ -100,5 +101,7 @@ uint32_t cpu_freq(void)
_cpu_frequency = PRCI_measure_mcycle_freq(3000, RTC_FREQ);
}
return _cpu_frequency;
#else
return CLOCK_CORECLOCK;
#endif
}

View File

@ -26,6 +26,7 @@
#define CPU_H
#include "thread.h"
#include "macros/units.h"
#include "vendor/platform.h"
#include "vendor/plic_driver.h"