diff options
-rw-r--r-- | bsp/drivers/fe300prci/fe300prci_driver.c | 39 | ||||
-rw-r--r-- | bsp/drivers/fe300prci/fe300prci_driver.h | 19 | ||||
-rw-r--r-- | bsp/drivers/plic/plic_driver.h | 6 | ||||
-rw-r--r-- | bsp/env/common.mk | 2 |
4 files changed, 50 insertions, 16 deletions
diff --git a/bsp/drivers/fe300prci/fe300prci_driver.c b/bsp/drivers/fe300prci/fe300prci_driver.c index 3338b81..9a16d5d 100644 --- a/bsp/drivers/fe300prci/fe300prci_driver.c +++ b/bsp/drivers/fe300prci/fe300prci_driver.c @@ -1,6 +1,6 @@ // See LICENSE file for license details -#include "drivers/fe300prci/fe300prci_driver.h" +#include "fe300prci/fe300prci_driver.h" #include "platform.h" #include <unistd.h> @@ -15,7 +15,7 @@ *(x) = lo | ((uint64_t) hi << 32); \ } -static uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq) +uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq) { uint32_t start_mtime = CLINT_REG(CLINT_MTIME); @@ -48,7 +48,7 @@ static uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_fr } -static void PRCI_use_hfrosc(int div, int trim) +void PRCI_use_hfrosc(int div, int trim) { // Make sure the HFROSC is running at its default setting // It is OK to change this even if we are running off of it. @@ -60,7 +60,7 @@ static void PRCI_use_hfrosc(int div, int trim) PRCI_REG(PRCI_PLLCFG) &= ~PLL_SEL(1); } -static void PRCI_use_pll(int refsel, int bypass, +void PRCI_use_pll(int refsel, int bypass, int r, int f, int q, int finaldiv, int hfroscdiv, int hfrosctrim) { @@ -70,7 +70,7 @@ static void PRCI_use_pll(int refsel, int bypass, PRCI_use_hfrosc(4, 16); } - // Set PLL Source to be HFXOSC if available. + // Set PLL Source to be HFXOSC if desired. uint32_t config_value = 0; config_value |= PLL_REFSEL(refsel); @@ -115,7 +115,7 @@ static void PRCI_use_pll(int refsel, int bypass, if (finaldiv == 1){ PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV_BY_1(1) | PLL_FINAL_DIV(0)); } else { - PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV(finaldiv)); + PRCI_REG(PRCI_PLLDIV) = (PLL_FINAL_DIV(finaldiv-1)); } PRCI_REG(PRCI_PLLCFG) = config_value; @@ -138,9 +138,16 @@ static void PRCI_use_pll(int refsel, int bypass, // Switch over to PLL Clock source PRCI_REG(PRCI_PLLCFG) |= PLL_SEL(1); + + // If we're running off HFXOSC, turn off the HFROSC to + // save power. + if (refsel) { + PRCI_REG(PRCI_HFROSCCFG) &= ~ROSC_EN(1); + } + } -static void PRCI_use_default_clocks() +void PRCI_use_default_clocks() { // Turn off the LFROSC AON_REG(AON_LFROSC) &= ~ROSC_EN(1); @@ -149,11 +156,25 @@ static void PRCI_use_default_clocks() PRCI_use_hfrosc(4, 16); } +void PRCI_use_hfxosc(uint32_t finaldiv) +{ + + PRCI_use_pll(1, // Use HFXTAL + 1, // Bypass = 1 + 0, // PLL settings don't matter + 0, // PLL settings don't matter + 0, // PLL settings don't matter + finaldiv, + -1, + -1); +} + // This is a generic function, which // doesn't span the entire range of HFROSC settings. // It only adjusts the trim, which can span a hundred MHz or so. -// This function needs improvement to ensure that the PLL settings -// are legal every step of the way. +// This function does not check the legality of the PLL settings +// at all, ant it is quite possible to configure invalid PLL settings +// this way. // It returns the actual measured CPU frequency. uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu) diff --git a/bsp/drivers/fe300prci/fe300prci_driver.h b/bsp/drivers/fe300prci/fe300prci_driver.h index 052edcb..75dcf00 100644 --- a/bsp/drivers/fe300prci/fe300prci_driver.h +++ b/bsp/drivers/fe300prci/fe300prci_driver.h @@ -3,19 +3,26 @@ #ifndef _FE300PRCI_DRIVER_H_ #define _FE300PRCI_DRIVER_H_ -#include <unistd.h> +__BEGIN_DECLS +#include <unistd.h> /* Measure and return the approximate frequency of the * CPU, as given by measuring the mcycle counter against * the mtime ticks. */ -static uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq); +uint32_t PRCI_measure_mcycle_freq(uint32_t mtime_ticks, uint32_t mtime_freq); /* Safely switch over to the HFROSC using the given div * and trim settings. */ -static void PRCI_use_hfrosc(int div, int trim); +void PRCI_use_hfrosc(int div, int trim); + +/* Safely switch over to the 16MHz HFXOSC, + * applying the finaldiv clock divider (1 is the lowest + * legal value). + */ +void PRCI_use_hfxosc(uint32_t finaldiv); /* Safely switch over to the PLL using the given * settings. @@ -27,7 +34,7 @@ static void PRCI_use_hfrosc(int div, int trim); * doesn't protect against you making it too fast or slow.) */ -static void PRCI_use_pll(int refsel, int bypass, +void PRCI_use_pll(int refsel, int bypass, int r, int f, int q, int finaldiv, int hfroscdiv, int hfrosctrim); @@ -36,7 +43,7 @@ static void PRCI_use_pll(int refsel, int bypass, * (on the current FE310 Dev Platforms, an external LFROSC is * used as it is more power efficient). */ -static void PRCI_use_default_clocks(); +void PRCI_use_default_clocks(); /* This routine will adjust the HFROSC trim * as the PLL clock source, measure the resulting @@ -50,5 +57,7 @@ static void PRCI_use_default_clocks(); */ uint32_t PRCI_set_hfrosctrim_for_f_cpu(uint32_t f_cpu); +__END_DECLS + #endif diff --git a/bsp/drivers/plic/plic_driver.h b/bsp/drivers/plic/plic_driver.h index 66410be..b14b442 100644 --- a/bsp/drivers/plic/plic_driver.h +++ b/bsp/drivers/plic/plic_driver.h @@ -3,6 +3,8 @@ #ifndef PLIC_DRIVER_H #define PLIC_DRIVER_H +__BEGIN_DECLS + #include "platform.h" typedef struct __plic_instance_t @@ -42,5 +44,7 @@ plic_source PLIC_claim_interrupt(plic_instance_t * this_plic); void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source); - + +__END_DECLS + #endif diff --git a/bsp/env/common.mk b/bsp/env/common.mk index c828306..74f5582 100644 --- a/bsp/env/common.mk +++ b/bsp/env/common.mk @@ -48,7 +48,7 @@ $(ASM_OBJS): %.o: %.S $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< $(C_OBJS): %.o: %.c $(HEADERS) - $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + $(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< .PHONY: clean clean: |