summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2023-08-30 19:07:24 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2023-08-30 19:07:24 +0000
commit6b45e5a92fd3f6a2980fe85725926ce08fab8779 (patch)
tree327bda4aac4afae810511b0cea4b75a22d8a8ddd /sys
parentd669d2a0e0390385dae42c29ef4e4fa5de23cde7 (diff)
Implement a few more clocks related to the GMAC.
ok jsing@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/riscv64/dev/stfclock.c97
1 files changed, 90 insertions, 7 deletions
diff --git a/sys/arch/riscv64/dev/stfclock.c b/sys/arch/riscv64/dev/stfclock.c
index 28bc339d6b1..2871bbf79f3 100644
--- a/sys/arch/riscv64/dev/stfclock.c
+++ b/sys/arch/riscv64/dev/stfclock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: stfclock.c,v 1.9 2023/08/01 18:20:07 kettenis Exp $ */
+/* $OpenBSD: stfclock.c,v 1.10 2023/08/30 19:07:23 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
* Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
@@ -498,6 +498,8 @@ stfclock_get_frequency_jh7110_aon(void *cookie, uint32_t *cells)
return clock_get_frequency(sc->sc_node, "stg_axiahb");
case JH7110_AONCLK_GMAC0_RMII_REFIN:
return clock_get_frequency(sc->sc_node, "gmac0_rmii_refin");
+ case JH7110_AONCLK_GMAC0_GTXCLK:
+ return clock_get_frequency(sc->sc_node, "gmac0_gtxclk");
}
reg = HREAD4(sc, idx * 4);
@@ -506,7 +508,7 @@ stfclock_get_frequency_jh7110_aon(void *cookie, uint32_t *cells)
switch (idx) {
case JH7110_AONCLK_GMAC0_TX:
- parent = mux ? JH7110_AONCLK_GMAC0_RMII_RTX:
+ parent = mux ? JH7110_AONCLK_GMAC0_RMII_RTX :
JH7110_AONCLK_GMAC0_GTXCLK;
return stfclock_get_frequency_jh7110_aon(sc, &parent);
}
@@ -540,11 +542,49 @@ stfclock_get_frequency_jh7110_aon(void *cookie, uint32_t *cells)
int
stfclock_set_frequency_jh7110_aon(void *cookie, uint32_t *cells, uint32_t freq)
{
+ struct stfclock_softc *sc = cookie;
uint32_t idx = cells[0];
+ uint32_t parent, parent_freq;
+ uint32_t reg, div, mux;
- printf("%s: not handled 0x%08x (freq=0x%08x)\n", __func__, idx, freq);
+ switch (idx) {
+ case JH7110_AONCLK_GMAC0_RMII_REFIN:
+ return clock_set_frequency(sc->sc_node, "gmac0_rmii_refin", freq);
+ case JH7110_AONCLK_GMAC0_GTXCLK:
+ return clock_set_frequency(sc->sc_node, "gmac0_gtxclk", freq);
+ }
- return -1;
+ reg = HREAD4(sc, idx * 4);
+ mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
+
+ switch (idx) {
+ case JH7110_AONCLK_GMAC0_TX:
+ parent = mux ? JH7110_AONCLK_GMAC0_RMII_RTX :
+ JH7110_AONCLK_GMAC0_GTXCLK;
+ return stfclock_set_frequency_jh7110_aon(sc, &parent, freq);
+ case JH7110_AONCLK_GMAC0_TX_INV:
+ parent = JH7110_AONCLK_GMAC0_TX;
+ return stfclock_set_frequency_jh7110_aon(sc, &parent, freq);
+ }
+
+ switch (idx) {
+ case JH7110_AONCLK_GMAC0_RMII_RTX:
+ parent = JH7110_AONCLK_GMAC0_RMII_REFIN;
+ break;
+ default:
+ printf("%s: not handled 0x%08x (freq=0x%08x)\n",
+ __func__, idx, freq);
+ return -1;
+ }
+
+ parent_freq = stfclock_get_frequency_jh7110_sys(sc, &parent);
+ div = parent_freq / freq;
+
+ reg &= ~CLKDIV_MASK;
+ reg |= (div << CLKDIV_SHIFT);
+ HWRITE4(sc, idx * 4, reg);
+
+ return 0;
}
void
@@ -807,6 +847,8 @@ stfclock_get_frequency_jh7110_sys(void *cookie, uint32_t *cells)
switch (idx) {
case JH7110_SYSCLK_OSC:
return clock_get_frequency(sc->sc_node, "osc");
+ case JH7110_SYSCLK_GMAC1_RMII_REFIN:
+ return clock_get_frequency(sc->sc_node, "gmac1_rmii_refin");
case JH7110_SYSCLK_PLL0_OUT:
return clock_get_frequency(sc->sc_node, "pll0_out");
case JH7110_SYSCLK_PLL1_OUT:
@@ -828,6 +870,10 @@ stfclock_get_frequency_jh7110_sys(void *cookie, uint32_t *cells)
mux = (reg >> 24) & 1;
parent = mux ? JH7110_SYSCLK_PLL2_OUT : JH7110_SYSCLK_OSC;
return stfclock_get_frequency_jh7110_sys(sc, &parent);
+ case JH7110_SYSCLK_GMAC1_TX:
+ parent = mux ? JH7110_SYSCLK_GMAC1_RMII_RTX :
+ JH7110_SYSCLK_GMAC1_GTXCLK;
+ return stfclock_get_frequency_jh7110_sys(sc, &parent);
}
switch (idx) {
@@ -916,7 +962,8 @@ stfclock_set_frequency_jh7110_sys(void *cookie, uint32_t *cells, uint32_t freq)
{
struct stfclock_softc *sc = cookie;
uint32_t idx = cells[0];
- uint32_t parent;
+ uint32_t parent, parent_freq;
+ uint32_t reg, div, mux;
switch (idx) {
case JH7110_SYSCLK_CPU_ROOT:
@@ -924,11 +971,47 @@ stfclock_set_frequency_jh7110_sys(void *cookie, uint32_t *cells, uint32_t 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);
}
- printf("%s: not handled 0x%08x (freq=0x%08x)\n", __func__, idx, freq);
+ reg = HREAD4(sc, idx * 4);
+ mux = (reg & CLKMUX_MASK) >> CLKMUX_SHIFT;
- return -1;
+ switch (idx) {
+ case JH7110_SYSCLK_GMAC1_TX:
+ parent = mux ? JH7110_SYSCLK_GMAC1_RMII_RTX :
+ JH7110_SYSCLK_GMAC1_GTXCLK;
+ return stfclock_set_frequency_jh7110_sys(sc, &parent, freq);
+ case JH7110_SYSCLK_GMAC1_TX_INV:
+ parent = JH7110_SYSCLK_GMAC1_TX;
+ return stfclock_set_frequency_jh7110_sys(sc, &parent, freq);
+ }
+
+ switch (idx) {
+ case JH7110_SYSCLK_GMAC1_GTXCLK:
+ parent = JH7110_SYSCLK_PLL0_OUT;
+ break;
+ case JH7110_SYSCLK_GMAC1_RMII_RTX:
+ parent = JH7110_SYSCLK_GMAC1_RMII_REFIN;
+ break;
+ case JH7110_SYSCLK_GMAC0_GTXCLK:
+ parent = JH7110_SYSCLK_PLL0_OUT;
+ break;
+ default:
+ printf("%s: not handled 0x%08x (freq=0x%08x)\n",
+ __func__, idx, freq);
+ return -1;
+ }
+
+ parent_freq = stfclock_get_frequency_jh7110_sys(sc, &parent);
+ div = parent_freq / freq;
+
+ reg &= ~CLKDIV_MASK;
+ reg |= (div << CLKDIV_SHIFT);
+ HWRITE4(sc, idx * 4, reg);
+
+ return 0;
}
void