Philipp Hug has uploaded this change for review. ( https://review.coreboot.org/28582
Change subject: soc/sifive/fu540: Update clock settings according SiFive bootloader ......................................................................
soc/sifive/fu540: Update clock settings according SiFive bootloader
The documentation unfortunately doesn't match what SiFive uses in their FSBL. Use the same values as in FSBL to make DDR RAM work.
Change-Id: I844cc41ed197333adeae495e71ea70b4a9603650 Signed-off-by: Philipp Hug philipp@hug.cx --- M src/soc/sifive/fu540/clock.c 1 file changed, 28 insertions(+), 8 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/82/28582/1
diff --git a/src/soc/sifive/fu540/clock.c b/src/soc/sifive/fu540/clock.c index a59a1e8..2651f5a 100644 --- a/src/soc/sifive/fu540/clock.c +++ b/src/soc/sifive/fu540/clock.c @@ -46,11 +46,13 @@ #define PRCI_COREPLLCFG0_DIVQ_SHIFT 15 #define PRCI_COREPLLCFG0_RANGE_SHIFT 18 #define PRCI_COREPLLCFG0_BYPASS_SHIFT 24 +#define PRCI_COREPLLCFG0_FSE_SHIFT 25 #define PRCI_COREPLLCFG0_DIVR_MASK (0x03f << PRCI_COREPLLCFG0_DIVR_SHIFT) #define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT) #define PRCI_COREPLLCFG0_DIVQ_MASK (0x007 << PRCI_COREPLLCFG0_DIVQ_SHIFT) #define PRCI_COREPLLCFG0_RANGE_MASK (0x07 << PRCI_COREPLLCFG0_RANGE_SHIFT) #define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT) +#define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
#define PRCI_DDRPLLCFG0_LOCK (1u << 31) #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 @@ -58,11 +60,13 @@ #define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15 #define PRCI_DDRPLLCFG0_RANGE_SHIFT 18 #define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24 +#define PRCI_DDRPLLCFG0_FSE_SHIFT 25 #define PRCI_DDRPLLCFG0_DIVR_MASK (0x03f << PRCI_DDRPLLCFG0_DIVR_SHIFT) #define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT) #define PRCI_DDRPLLCFG0_DIVQ_MASK (0x007 << PRCI_DDRPLLCFG0_DIVQ_SHIFT) #define PRCI_DDRPLLCFG0_RANGE_MASK (0x07 << PRCI_DDRPLLCFG0_RANGE_SHIFT) #define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT) +#define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
#define PRCI_DDRPLLCFG1_MASK (1u << 31)
@@ -83,18 +87,28 @@ #define PRCI_CORECLK_DIVF 59 #define PRCI_CORECLK_DIVQ 2 #define PRCI_CORECLK_RANGE 4 +#define PRCI_CORECLK_BYPASS 0 +#define PRCI_CORECLK_FSE 1
/* * Section 7.4.3: DDR and Ethernet Subsystem Clocking and Reset - * GEMGXLPLL is set up for 125 MHz output frequency. - * divr = 0, divf = 59 (4000 MHz VCO), divq = 5 DDRPLL is set up to run at the + * + * Unfortunately the documentation example doesn't match the HiFive + * Unleashed board settings. + * Configuration values taken from SiFive FSBL: + * https://github.com/sifive/freedom-u540-c000-bootloader/blob/master/fsbl/main... + * + * GEMGXLPLL is set up for 933 MHz output frequency. + * divr = 0, divf = 55 (4000 MHz VCO), divq = 2 DDRPLL is set up to run at the * memory MT/s divided by 4. */
#define PRCI_DDRCLK_DIVR 0 -#define PRCI_DDRCLK_DIVF 59 -#define PRCI_DDRCLK_DIVQ 5 +#define PRCI_DDRCLK_DIVF 55 +#define PRCI_DDRCLK_DIVQ 2 #define PRCI_DDRCLK_RANGE 4 +#define PRCI_DDRCLK_BYPASS 0 +#define PRCI_DDRCLK_FSE 1
// 33.33 Mhz after reset #define FU540_BASE_FQY 33330 @@ -108,11 +122,14 @@ u32 c = read32(&prci->corepllcfg0); clrsetbits_le32(&c, PRCI_COREPLLCFG0_DIVR_MASK | PRCI_COREPLLCFG0_DIVF_MASK | PRCI_COREPLLCFG0_DIVQ_MASK - | PRCI_COREPLLCFG0_RANGE_MASK | PRCI_COREPLLCFG0_BYPASS_MASK, + | PRCI_COREPLLCFG0_RANGE_MASK | PRCI_COREPLLCFG0_BYPASS_MASK + | PRCI_COREPLLCFG0_FSE_MASK, (PRCI_CORECLK_DIVR << PRCI_COREPLLCFG0_DIVR_SHIFT) | (PRCI_CORECLK_DIVF << PRCI_COREPLLCFG0_DIVF_SHIFT) | (PRCI_CORECLK_DIVQ << PRCI_COREPLLCFG0_DIVQ_SHIFT) - | (PRCI_CORECLK_RANGE << PRCI_COREPLLCFG0_RANGE_SHIFT)); + | (PRCI_CORECLK_RANGE << PRCI_COREPLLCFG0_RANGE_SHIFT) + | (PRCI_CORECLK_BYPASS << PRCI_COREPLLCFG0_BYPASS_SHIFT) + | (PRCI_CORECLK_FSE << PRCI_COREPLLCFG0_FSE_SHIFT)); write32(&prci->corepllcfg0, c);
// wait for PLL lock @@ -134,11 +151,14 @@ u32 c = read32(&prci->ddrpllcfg0); clrsetbits_le32(&c, PRCI_DDRPLLCFG0_DIVR_MASK | PRCI_DDRPLLCFG0_DIVF_MASK | PRCI_DDRPLLCFG0_DIVQ_MASK - | PRCI_DDRPLLCFG0_RANGE_MASK | PRCI_DDRPLLCFG0_BYPASS_MASK, + | PRCI_DDRPLLCFG0_RANGE_MASK | PRCI_DDRPLLCFG0_BYPASS_MASK + | PRCI_DDRPLLCFG0_FSE_MASK, (PRCI_DDRCLK_DIVR << PRCI_DDRPLLCFG0_DIVR_SHIFT) | (PRCI_DDRCLK_DIVF << PRCI_DDRPLLCFG0_DIVF_SHIFT) | (PRCI_DDRCLK_DIVQ << PRCI_DDRPLLCFG0_DIVQ_SHIFT) - | (PRCI_DDRCLK_RANGE << PRCI_DDRPLLCFG0_RANGE_SHIFT)); + | (PRCI_DDRCLK_RANGE << PRCI_DDRPLLCFG0_RANGE_SHIFT) + | (PRCI_DDRCLK_BYPASS << PRCI_DDRPLLCFG0_BYPASS_SHIFT) + | (PRCI_DDRCLK_FSE << PRCI_DDRPLLCFG0_FSE_SHIFT)); write32(&prci->ddrpllcfg0, c);
// wait for PLL lock