Philipp Hug has uploaded this change for review. ( https://review.coreboot.org/28602
Change subject: soc/sifive/fu540: Switch clock to 1GHz in romstage ......................................................................
soc/sifive/fu540: Switch clock to 1GHz in romstage
Invoke clock_init in romstage for SiFive Unleashed. Change-Id: Ib869762d557e8fdf4c83a53698102df116d80389 --- M src/mainboard/sifive/hifive-unleashed/romstage.c M src/soc/sifive/fu540/Makefile.inc M src/soc/sifive/fu540/clock.c 3 files changed, 45 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/02/28602/1
diff --git a/src/mainboard/sifive/hifive-unleashed/romstage.c b/src/mainboard/sifive/hifive-unleashed/romstage.c index ea6efb9..9729f86 100644 --- a/src/mainboard/sifive/hifive-unleashed/romstage.c +++ b/src/mainboard/sifive/hifive-unleashed/romstage.c @@ -13,8 +13,13 @@ * GNU General Public License for more details. */
+#include <cbmem.h> #include <console/console.h> +#include <console/streams.h> +#include <console/uart.h> #include <program_loading.h> +#include <soc/clock.h> +#include <soc/sdram.h>
void main(void) { @@ -22,5 +27,18 @@
/* TODO: Follow Section 6.3 (FSBL) of the FU540 manual */
+ /* + * Flush console before changing clock/UART divisor to prevent garbage + * being printed. + */ + console_tx_flush(); + + clock_init(); + + // re-initialize UART + #if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) + uart_init(CONFIG_UART_FOR_CONSOLE); + #endif + run_ramstage(); } diff --git a/src/soc/sifive/fu540/Makefile.inc b/src/soc/sifive/fu540/Makefile.inc index b991783..ed1836e 100644 --- a/src/soc/sifive/fu540/Makefile.inc +++ b/src/soc/sifive/fu540/Makefile.inc @@ -22,6 +22,7 @@ romstage-y += media.c romstage-y += sdram.c romstage-y += otp.c +romstage-y += clock.c
ramstage-y += uart.c ramstage-y += clint.c @@ -29,6 +30,7 @@ ramstage-y += sdram.c ramstage-y += cbmem.c ramstage-y += otp.c +ramstage-y += clock.c
CPPFLAGS_common += -Isrc/soc/sifive/fu540/include
diff --git a/src/soc/sifive/fu540/clock.c b/src/soc/sifive/fu540/clock.c index a98a093..5fcf5bd 100644 --- a/src/soc/sifive/fu540/clock.c +++ b/src/soc/sifive/fu540/clock.c @@ -198,8 +198,33 @@ / (1ul << divq); }
+#define FU540_UART_DEVICES 2 +#define FU540_UART_REG_DIV 0x18 +#define FU540_UART_DIV_VAL 4 + +#define FU540_SPI_DIV 0x00 +#define FU540_SPI_DIV_VAL 4 + + +void static update_peripheral_clock_dividers(void) +{ + write32((uint32_t *)(FU540_QSPI0 + FU540_SPI_DIV), FU540_SPI_DIV_VAL); + write32((uint32_t *)(FU540_QSPI1 + FU540_SPI_DIV), FU540_SPI_DIV_VAL); + write32((uint32_t *)(FU540_QSPI2 + FU540_SPI_DIV), FU540_SPI_DIV_VAL); + + for (size_t i = 0; i < FU540_UART_DEVICES; i++) { + write32((uint32_t *)(FU540_UART(i) + FU540_UART_REG_DIV), FU540_UART_DIV_VAL); + } +} + void clock_init(void) { + /* + * Update the peripheral clock dividers of UART, SPI and I2C to safe + * values as we can't put them in reset before changing frequency. + */ + update_peripheral_clock_dividers(); + init_coreclk();
// put DDR and ethernet in reset