Add support for the RK3568 32k RTC clock. This clock uses a fractional
authorkettenis <kettenis@openbsd.org>
Sun, 26 Mar 2023 10:41:42 +0000 (10:41 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 26 Mar 2023 10:41:42 +0000 (10:41 +0000)
divider so rework the RK3399 support for fractional dividers to be more
general and reuse it.

ok dlg@

sys/dev/fdt/rkclock.c
sys/dev/fdt/rkclock_clocks.h

index b56dcfe..41f455d 100644 (file)
@@ -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 <kettenis@openbsd.org>
  *
@@ -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;
        }
index 76159c1..60537ea 100644 (file)
 #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 */
 #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
 #define RK3568_PCLK_I2C0               45
 #define RK3568_CLK_PDPMU               49
 
-#define RK3568_PPLL_PH0                        1022
+#define RK3568_PPLL_PH0                        1021
 
 /*
  * RK3588 clocks.