The branch main has been updated by manu:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=731e418bd748f6602bb184ca3a35bab8af241cf1

commit 731e418bd748f6602bb184ca3a35bab8af241cf1
Author:     Emmanuel Vadot <m...@freebsd.org>
AuthorDate: 2021-09-09 16:24:33 +0000
Commit:     Emmanuel Vadot <m...@freebsd.org>
CommitDate: 2021-09-15 16:43:04 +0000

    arm64: rockchip: clk_mux: Add support for mux in GRF type clock
    
    Some clocks have their mux register in the GRF and not in the CRU.
    Add support for that in the rk_clk_mux clock type.
---
 sys/arm64/rockchip/clk/rk_clk_mux.c | 50 ++++++++++++++++++++++++++++++++++---
 sys/arm64/rockchip/clk/rk_clk_mux.h |  1 +
 sys/arm64/rockchip/clk/rk_cru.h     | 17 +++++++++++++
 3 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/sys/arm64/rockchip/clk/rk_clk_mux.c 
b/sys/arm64/rockchip/clk/rk_clk_mux.c
index eb3cdeb99f4b..20e612b8c764 100644
--- a/sys/arm64/rockchip/clk/rk_clk_mux.c
+++ b/sys/arm64/rockchip/clk/rk_clk_mux.c
@@ -38,11 +38,13 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <dev/extres/clk/clk.h>
+#include <dev/extres/syscon/syscon.h>
 
 #include <arm64/rockchip/clk/rk_cru.h>
 #include <arm64/rockchip/clk/rk_clk_mux.h>
 
 #include "clkdev_if.h"
+#include "syscon_if.h"
 
 #define        WR4(_clk, off, val)                                             
\
        CLKDEV_WRITE_4(clknode_get_device(_clk), off, val)
@@ -72,6 +74,7 @@ struct rk_clk_mux_sc {
        uint32_t        shift;
        uint32_t        mask;
        int             mux_flags;
+       struct syscon   *grf;
 };
 
 static clknode_method_t rk_clk_mux_methods[] = {
@@ -84,6 +87,25 @@ static clknode_method_t rk_clk_mux_methods[] = {
 DEFINE_CLASS_1(rk_clk_mux, rk_clk_mux_class, rk_clk_mux_methods,
    sizeof(struct rk_clk_mux_sc), clknode_class);
 
+static struct syscon *
+rk_clk_mux_get_grf(struct clknode *clk)
+{
+       device_t dev;
+       phandle_t node;
+       struct syscon *grf;
+
+       grf = NULL;
+       dev = clknode_get_device(clk);
+       node = ofw_bus_get_node(dev);
+       if (OF_hasprop(node, "rockchip,grf") &&
+           syscon_get_by_ofw_property(dev, node,
+           "rockchip,grf", &grf) != 0) {
+               return (NULL);
+       }
+
+       return (grf);
+}
+
 static int
 rk_clk_mux_init(struct clknode *clk, device_t dev)
 {
@@ -93,8 +115,19 @@ rk_clk_mux_init(struct clknode *clk, device_t dev)
 
        sc = clknode_get_softc(clk);
 
+       if ((sc->mux_flags & RK_CLK_MUX_GRF) != 0) {
+               sc->grf = rk_clk_mux_get_grf(clk);
+               if (sc->grf == NULL)
+                       panic("clock %s has GRF flag set but no syscon is 
available",
+                           clknode_get_name(clk));
+       }
+
        DEVICE_LOCK(clk);
-       rv = RD4(clk, sc->offset, &reg);
+       if (sc->grf) {
+               reg = SYSCON_READ_4(sc->grf, sc->offset);
+               rv = 0;
+       } else
+               rv = RD4(clk, sc->offset, &reg);
        DEVICE_UNLOCK(clk);
        if (rv != 0) {
                return (rv);
@@ -114,13 +147,18 @@ rk_clk_mux_set_mux(struct clknode *clk, int idx)
        sc = clknode_get_softc(clk);
 
        DEVICE_LOCK(clk);
-       rv = MD4(clk, sc->offset, sc->mask << sc->shift,
-           ((idx & sc->mask) << sc->shift) | RK_CLK_MUX_MASK);
+       if (sc->grf)
+               rv = SYSCON_MODIFY_4(sc->grf, sc->offset, sc->mask << sc->shift,
+                 ((idx & sc->mask) << sc->shift) | RK_CLK_MUX_MASK);
+       else
+               rv = MD4(clk, sc->offset, sc->mask << sc->shift,
+                 ((idx & sc->mask) << sc->shift) | RK_CLK_MUX_MASK);
        if (rv != 0) {
                DEVICE_UNLOCK(clk);
                return (rv);
        }
-       RD4(clk, sc->offset, &reg);
+       if (sc->grf == NULL)
+               RD4(clk, sc->offset, &reg);
        DEVICE_UNLOCK(clk);
 
        return(0);
@@ -138,6 +176,10 @@ rk_clk_mux_set_freq(struct clknode *clk, uint64_t fparent, 
uint64_t *fout,
 
        sc = clknode_get_softc(clk);
 
+       if ((sc->mux_flags & RK_CLK_MUX_GRF) != 0) {
+               *stop = 1;
+               return (ENOTSUP);
+       }
        if ((sc->mux_flags & RK_CLK_MUX_REPARENT) == 0) {
                *stop = 0;
                return (0);
diff --git a/sys/arm64/rockchip/clk/rk_clk_mux.h 
b/sys/arm64/rockchip/clk/rk_clk_mux.h
index 7825f8892ac3..c2b5f9cdad69 100644
--- a/sys/arm64/rockchip/clk/rk_clk_mux.h
+++ b/sys/arm64/rockchip/clk/rk_clk_mux.h
@@ -42,6 +42,7 @@ struct rk_clk_mux_def {
 
 #define        RK_CLK_MUX_MASK         0xFFFF0000
 #define        RK_CLK_MUX_REPARENT     (1 << 0)
+#define        RK_CLK_MUX_GRF          (1 << 1)
 
 int rk_clk_mux_register(struct clkdom *clkdom, struct rk_clk_mux_def *clkdef);
 
diff --git a/sys/arm64/rockchip/clk/rk_cru.h b/sys/arm64/rockchip/clk/rk_cru.h
index 0d1c49f01290..1c749d1d2c87 100644
--- a/sys/arm64/rockchip/clk/rk_cru.h
+++ b/sys/arm64/rockchip/clk/rk_cru.h
@@ -186,6 +186,23 @@
        },                                                              \
 }
 
+/* Complex clock without divider (multiplexer only in GRF). */
+#define MUXGRF(_id, _name, _pn, _f,  _mo, _ms, _mw)                    \
+{                                                                      \
+       .type = RK_CLK_MUX,                                             \
+       .clk.mux = &(struct rk_clk_mux_def) {                           \
+               .clkdef.id = _id,                                       \
+               .clkdef.name = _name,                                   \
+               .clkdef.parent_names = _pn,                             \
+               .clkdef.parent_cnt = nitems(_pn),                       \
+               .clkdef.flags = CLK_NODE_STATIC_STRINGS,                \
+               .offset = _mo,                                          \
+               .shift = _ms,                                           \
+               .width = _mw,                                           \
+               .mux_flags = RK_CLK_MUX_GRF | _f,                       \
+       },                                                              \
+}
+
 struct rk_cru_gate {
        const char      *name;
        const char      *parent_name;
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to