From a21015c5ead22347daa708f0180a445f6388314b Mon Sep 17 00:00:00 2001 From: kettenis Date: Sun, 26 Mar 2023 10:41:42 +0000 Subject: [PATCH] Add support for the RK3568 32k RTC clock. This clock uses a fractional divider so rework the RK3399 support for fractional dividers to be more general and reuse it. ok dlg@ --- sys/dev/fdt/rkclock.c | 29 +++++++++++++++++++++++------ sys/dev/fdt/rkclock_clocks.h | 35 +++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/sys/dev/fdt/rkclock.c b/sys/dev/fdt/rkclock.c index b56dcfe89a6..41f455d3603 100644 --- a/sys/dev/fdt/rkclock.c +++ b/sys/dev/fdt/rkclock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rkclock.c,v 1.71 2023/03/23 13:15:02 jsg Exp $ */ +/* $OpenBSD: rkclock.c,v 1.72 2023/03/26 10:41:42 kettenis Exp $ */ /* * Copyright (c) 2017, 2018 Mark Kettenis * @@ -2749,19 +2749,22 @@ rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq) } uint32_t -rk3399_get_frac(struct rkclock_softc *sc, int parent, bus_size_t base) +rk3399_get_frac(struct rkclock_softc *sc, uint32_t parent, bus_size_t base) { - uint32_t frac; + uint32_t parent_freq, frac; uint16_t n, d; frac = HREAD4(sc, base); n = frac >> 16; d = frac & 0xffff; - return ((uint64_t)rkclock_get_frequency(sc, parent) * n) / d; + if (n == 0 || d == 0) + n = d = 1; + parent_freq = sc->sc_cd.cd_get_frequency(sc, &parent); + return ((uint64_t)parent_freq * n) / d; } int -rk3399_set_frac(struct rkclock_softc *sc, int parent, bus_size_t base, +rk3399_set_frac(struct rkclock_softc *sc, uint32_t parent, bus_size_t base, uint32_t freq) { uint32_t n, d; @@ -2770,7 +2773,7 @@ rk3399_set_frac(struct rkclock_softc *sc, int parent, bus_size_t base, uint32_t a, tmp; n = freq; - d = rkclock_get_frequency(sc, parent); + d = sc->sc_cd.cd_get_frequency(sc, &parent); /* * The denominator needs to be at least 20 times the numerator @@ -3566,6 +3569,12 @@ rk3568_reset(void *cookie, uint32_t *cells, int on) /* PMUCRU */ const struct rkclock rk3568_pmu_clocks[] = { + { + RK3568_CLK_RTC_32K, RK3568_PMUCRU_CLKSEL_CON(0), + SEL(7, 6), 0, + { 0, RK3568_XIN32K, RK3568_CLK_RTC32K_FRAC }, + SET_PARENT + }, { RK3568_CLK_I2C0, RK3568_PMUCRU_CLKSEL_CON(3), 0, DIV(15, 7), @@ -3724,9 +3733,14 @@ rk3568_pmu_get_frequency(void *cookie, uint32_t *cells) return rk3328_get_pll(sc, RK3568_PMUCRU_PPLL_CON(0)); case RK3568_PLL_HPLL: return rk3328_get_pll(sc, RK3568_PMUCRU_HPLL_CON(0)); + case RK3568_CLK_RTC32K_FRAC: + return rk3399_get_frac(sc, RK3568_XIN24M, + RK3568_PMUCRU_CLKSEL_CON(1)); case RK3568_PPLL_PH0: idx = RK3568_PLL_PPLL; return rk3568_get_frequency(sc, &idx) / 2; + case RK3568_XIN32K: + return 32768; case RK3568_XIN24M: return 24000000; default: @@ -3747,6 +3761,9 @@ rk3568_pmu_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_PPLL_CON(0), freq); case RK3568_PLL_HPLL: return rk3568_pmu_set_pll(sc, RK3568_PMUCRU_HPLL_CON(0), freq); + case RK3568_CLK_RTC32K_FRAC: + return rk3399_set_frac(sc, RK3568_XIN24M, + RK3568_PMUCRU_CLKSEL_CON(1), freq); default: break; } diff --git a/sys/dev/fdt/rkclock_clocks.h b/sys/dev/fdt/rkclock_clocks.h index 76159c10fed..60537ea4c5d 100644 --- a/sys/dev/fdt/rkclock_clocks.h +++ b/sys/dev/fdt/rkclock_clocks.h @@ -332,21 +332,22 @@ #define RK3568_CPLL_25M 416 #define RK3568_CPLL_100M 417 -#define RK3568_SCLK_GMAC0_DIV_50 1008 -#define RK3568_SCLK_GMAC0_DIV_5 1009 -#define RK3568_SCLK_GMAC0_DIV_20 1010 -#define RK3568_SCLK_GMAC0_DIV_2 1011 -#define RK3568_SCLK_GMAC1_DIV_50 1012 -#define RK3568_SCLK_GMAC1_DIV_5 1013 -#define RK3568_SCLK_GMAC1_DIV_20 1014 -#define RK3568_SCLK_GMAC1_DIV_2 1015 -#define RK3568_GPLL_400M 1016 -#define RK3568_GPLL_300M 1017 -#define RK3568_GPLL_200M 1018 -#define RK3568_GPLL_100M 1019 -#define RK3568_CLK_OSC0_DIV_750K 1020 -#define RK3568_GMAC0_CLKIN 1021 -#define RK3568_GMAC1_CLKIN 1022 +#define RK3568_SCLK_GMAC0_DIV_50 1007 +#define RK3568_SCLK_GMAC0_DIV_5 1008 +#define RK3568_SCLK_GMAC0_DIV_20 1009 +#define RK3568_SCLK_GMAC0_DIV_2 1010 +#define RK3568_SCLK_GMAC1_DIV_50 1011 +#define RK3568_SCLK_GMAC1_DIV_5 1012 +#define RK3568_SCLK_GMAC1_DIV_20 1013 +#define RK3568_SCLK_GMAC1_DIV_2 1014 +#define RK3568_GPLL_400M 1015 +#define RK3568_GPLL_300M 1016 +#define RK3568_GPLL_200M 1017 +#define RK3568_GPLL_100M 1018 +#define RK3568_CLK_OSC0_DIV_750K 1019 +#define RK3568_GMAC0_CLKIN 1020 +#define RK3568_GMAC1_CLKIN 1021 +#define RK3568_XIN32K 1022 #define RK3568_XIN24M 1023 /* PMUCRU */ @@ -354,7 +355,9 @@ #define RK3568_PLL_PPLL 1 #define RK3568_PLL_HPLL 2 +#define RK3568_CLK_RTC_32K 5 #define RK3568_CLK_I2C0 7 +#define RK3568_CLK_RTC32K_FRAC 8 #define RK3568_SCLK_UART0 11 #define RK3568_CLK_PCIEPHY0_DIV 29 #define RK3568_CLK_PCIEPHY0_OSC0 30 @@ -370,7 +373,7 @@ #define RK3568_PCLK_I2C0 45 #define RK3568_CLK_PDPMU 49 -#define RK3568_PPLL_PH0 1022 +#define RK3568_PPLL_PH0 1021 /* * RK3588 clocks. -- 2.20.1