From d1efa468b4621baf72d8645ae750741c2ca6d85e Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 19 Sep 2023 19:15:08 +0000 Subject: [PATCH] Instead of adjusting PLL0 to scale the CPU frequency, use the divider of the actual CPU clock. This prevents one of the GMAC0 clocks changing when we change the CPU frequency, which would break one of the Ethernet ports on the VisionFive 2 v1.2a. However, since the firmware configures PLL0 to 1 GHz, we still need to bump it up to 1.5 GHz in order to reach the highest supported CPU clock rates. ok jmatthew@, jca@, jsing@ --- sys/arch/riscv64/dev/stfclock.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sys/arch/riscv64/dev/stfclock.c b/sys/arch/riscv64/dev/stfclock.c index 2871bbf79f3..8684cbd059f 100644 --- a/sys/arch/riscv64/dev/stfclock.c +++ b/sys/arch/riscv64/dev/stfclock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: stfclock.c,v 1.10 2023/08/30 19:07:23 kettenis Exp $ */ +/* $OpenBSD: stfclock.c,v 1.11 2023/09/19 19:15:08 kettenis Exp $ */ /* * Copyright (c) 2022 Mark Kettenis * Copyright (c) 2023 Joel Sing @@ -966,15 +966,31 @@ stfclock_set_frequency_jh7110_sys(void *cookie, uint32_t *cells, uint32_t freq) uint32_t reg, div, mux; switch (idx) { - case JH7110_SYSCLK_CPU_ROOT: - return clock_set_frequency(sc->sc_node, "pll0_out", freq); - case JH7110_SYSCLK_CPU_CORE: - parent = JH7110_SYSCLK_CPU_ROOT; - return stfclock_set_frequency_jh7110_sys(sc, &parent, freq); case JH7110_SYSCLK_GMAC1_RMII_REFIN: return clock_set_frequency(sc->sc_node, "gmac1_rmii_refin", freq); } + /* + * Firmware on the VisionFive 2 initializes PLL0 to 1 GHz and + * runs the CPU cores at this frequency. But there is no + * operating point in the device tree with this frequency and + * it means we can't run at the supported maximum frequency of + * 1.5 GHz. + * + * So if we're switching away from the 1 GHz boot frequency, + * bump the PLL0 frequency up to 1.5 GHz. But set the divider + * for the CPU clock to 2 to make sure we don't run at a + * frequency that is too high for the default CPU voltage. + */ + if (idx == JH7110_SYSCLK_CPU_CORE && freq != 1000000000 && + stfclock_get_frequency_jh7110_sys(sc, &idx) == 1000000000) { + reg = HREAD4(sc, idx * 4); + reg &= ~CLKDIV_MASK; + reg |= (2 << CLKDIV_SHIFT); + HWRITE4(sc, idx * 4, reg); + clock_set_frequency(sc->sc_node, "pll0_out", 1500000000); + } + reg = HREAD4(sc, idx * 4); mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT; @@ -989,6 +1005,9 @@ stfclock_set_frequency_jh7110_sys(void *cookie, uint32_t *cells, uint32_t freq) } switch (idx) { + case JH7110_SYSCLK_CPU_CORE: + parent = JH7110_SYSCLK_CPU_ROOT; + break; case JH7110_SYSCLK_GMAC1_GTXCLK: parent = JH7110_SYSCLK_PLL0_OUT; break; -- 2.20.1