summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Hug <philipp@hug.cx>2018-09-10 17:35:45 +0200
committerRonald G. Minnich <rminnich@gmail.com>2018-09-13 15:33:57 +0000
commitbdd866e38a391d557f3a052cac0bb6387d9c4c24 (patch)
tree36f3e98ff32a51f009e66c1542120a701d826f45 /src
parent18764a328da0cf39ad83a658f9b84b99f220a30c (diff)
soc/sifive/fu540: Get SDRAM controller out of reset
Change-Id: Ifa6faffbaf353379f57e0f80c1c4ca2fc380f874 Signed-off-by: Philipp Hug <philipp@hug.cx> Reviewed-on: https://review.coreboot.org/28583 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Diffstat (limited to 'src')
-rw-r--r--src/soc/sifive/fu540/clock.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/soc/sifive/fu540/clock.c b/src/soc/sifive/fu540/clock.c
index 9b396a78a1..a98a09367c 100644
--- a/src/soc/sifive/fu540/clock.c
+++ b/src/soc/sifive/fu540/clock.c
@@ -72,6 +72,12 @@ static struct prci_ctlr *prci = (void *)FU540_PRCI;
#define PRCI_CORECLKSEL_CORECLKSEL 1
+#define PRCI_DEVICESRESET_DDR_CTRL_RST_N(x) (((x) & 0x1) << 0)
+#define PRCI_DEVICESRESET_DDR_AXI_RST_N(x) (((x) & 0x1) << 1)
+#define PRCI_DEVICESRESET_DDR_AHB_RST_N(x) (((x) & 0x1) << 2)
+#define PRCI_DEVICESRESET_DDR_PHY_RST_N(x) (((x) & 0x1) << 3)
+#define PRCI_DEVICESRESET_GEMGXL_RST_N(x) (((x) & 0x1) << 5)
+
/*
* Set coreclk according to the SiFive FU540-C000 Manual
* https://www.sifive.com/documentation/chips/freedom-u540-c000-manual/
@@ -198,5 +204,33 @@ void clock_init(void)
// put DDR and ethernet in reset
write32(&prci->devicesresetreg, 0);
+
init_pll_ddr();
+
+ // The following code and its comments is mostly derived from the SiFive
+ // u540 bootloader.
+ // https://github.com/sifive/freedom-u540-c000-bootloader
+
+ // get DDR out of reset
+ write32(&prci->devicesresetreg, PRCI_DEVICESRESET_DDR_CTRL_RST_N(1));
+
+ // HACK to get the '1 full controller clock cycle'.
+ asm volatile ("fence");
+
+ // get DDR out of reset
+ write32(&prci->devicesresetreg,
+ PRCI_DEVICESRESET_DDR_CTRL_RST_N(1) |
+ PRCI_DEVICESRESET_DDR_AXI_RST_N(1) |
+ PRCI_DEVICESRESET_DDR_AHB_RST_N(1) |
+ PRCI_DEVICESRESET_DDR_PHY_RST_N(1));
+
+ // HACK to get the '1 full controller clock cycle'.
+ asm volatile ("fence");
+
+ // These take like 16 cycles to actually propagate. We can't go sending
+ // stuff before they come out of reset. So wait.
+ // TODO: Add a register to read the current reset states, or DDR Control
+ // device?
+ for (int i = 0; i < 256; i++)
+ asm volatile ("nop");
}