summaryrefslogtreecommitdiff
path: root/bsp/drivers
diff options
context:
space:
mode:
authorMegan Wachs <megan@sifive.com>2017-02-01 16:39:38 -0800
committerMegan Wachs <megan@sifive.com>2017-02-01 16:39:38 -0800
commit08a72bb956a25fd94d965fb4474f3ddcca1ed1e6 (patch)
tree41f952ee81ce917aa6be874b226d98741008b2fd /bsp/drivers
parent0adc37422f48e9468d980a1d98dcc65bd7ab3043 (diff)
Additional PRCI driver support. Make the code usable by C++ programs as well.
Diffstat (limited to 'bsp/drivers')
-rw-r--r--bsp/drivers/fe300prci/fe300prci_driver.c39
-rw-r--r--bsp/drivers/fe300prci/fe300prci_driver.h19
-rw-r--r--bsp/drivers/plic/plic_driver.h6
3 files changed, 49 insertions, 15 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