Author: mhorne
Date: Sat Feb  1 17:09:56 2020
New Revision: 357369
URL: https://svnweb.freebsd.org/changeset/base/357369

Log:
  prci: register the DDR and GEMGX PLLs
  
  The PRCI module exports three PLLs. Currently only the coreclk/corepll
  is registered, so add the logic to register the DDR (memory) and GEMGX
  (ethernet) clocks as well. These clocks are unused at the moment.
  
  Reviewed by:  kp
  Differential Revision:        https://reviews.freebsd.org/D23404

Modified:
  head/sys/riscv/sifive/fu540_prci.c

Modified: head/sys/riscv/sifive/fu540_prci.c
==============================================================================
--- head/sys/riscv/sifive/fu540_prci.c  Sat Feb  1 17:03:31 2020        
(r357368)
+++ head/sys/riscv/sifive/fu540_prci.c  Sat Feb  1 17:09:56 2020        
(r357369)
@@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
 #include <dev/ofw/ofw_bus_subr.h>
 #include <dev/ofw/openfirm.h>
 
+#include <gnu/dts/include/dt-bindings/clock/sifive-fu540-prci.h>
+
 static struct resource_spec prci_spec[] = {
        { SYS_RES_MEMORY, 0, RF_ACTIVE },
        RESOURCE_SPEC_END
@@ -68,6 +70,7 @@ struct prci_softc {
 
 struct prci_clk_pll_sc {
        struct prci_softc       *parent_sc;
+       uint32_t                reg;
 };
 
 #define        PRCI_LOCK(sc)                   mtx_lock(&(sc)->mtx)
@@ -75,17 +78,40 @@ struct prci_clk_pll_sc {
 #define        PRCI_ASSERT_LOCKED(sc)          mtx_assert(&(sc)->mtx, 
MA_OWNED);
 #define        PRCI_ASSERT_UNLOCKED(sc)        mtx_assert(&(sc)->mtx, 
MA_NOTOWNED);
 
-#define        PRCI_COREPLL                    0x4
-#define                PRCI_COREPLL_DIVR_MASK  0x3f
-#define                PRCI_COREPLL_DIVR_SHIFT 0
-#define                PRCI_COREPLL_DIVF_MASK  0x7fc0
-#define                PRCI_COREPLL_DIVF_SHIFT 6
-#define                PRCI_COREPLL_DIVQ_MASK  0x38000
-#define                PRCI_COREPLL_DIVQ_SHIFT 15
+#define        PRCI_COREPLL_CFG0               0x4
+#define        PRCI_DDRPLL_CFG0                0xC
+#define        PRCI_GEMGXLPLL_CFG0             0x1C
 
+#define        PRCI_PLL_DIVR_MASK              0x3f
+#define        PRCI_PLL_DIVR_SHIFT             0
+#define        PRCI_PLL_DIVF_MASK              0x7fc0
+#define        PRCI_PLL_DIVF_SHIFT             6
+#define        PRCI_PLL_DIVQ_MASK              0x38000
+#define        PRCI_PLL_DIVQ_SHIFT             15
+
 #define        PRCI_READ(_sc, _reg)            \
     bus_space_read_4((_sc)->bst, (_sc)->bsh, (_reg))
 
+struct prci_pll_def {
+       uint32_t        id;
+       const char      *name;
+       uint32_t        reg;
+};
+
+#define PLL(_id, _name, _base)                                 \
+{                                                              \
+       .id = (_id),                                            \
+       .name = (_name),                                        \
+       .reg = (_base),                                         \
+}
+
+/* PLL Clocks */
+struct prci_pll_def pll_clks[] = {
+       PLL(PRCI_CLK_COREPLL, "coreclk",  PRCI_COREPLL_CFG0),
+       PLL(PRCI_CLK_DDRPLL, "ddrclk",   PRCI_DDRPLL_CFG0),
+       PLL(PRCI_CLK_GEMGXLPLL, "gemgxclk", PRCI_GEMGXLPLL_CFG0),
+};
+
 static int
 prci_clk_pll_init(struct clknode *clk, device_t dev)
 {
@@ -121,11 +147,11 @@ prci_clk_pll_recalc(struct clknode *clk, uint64_t *fre
        }
 
        /* Calculate the PLL output */
-       val = PRCI_READ(sc->parent_sc, PRCI_COREPLL);
+       val = PRCI_READ(sc->parent_sc, sc->reg);
 
-       divf = (val & PRCI_COREPLL_DIVF_MASK) >> PRCI_COREPLL_DIVF_SHIFT;
-       divq = (val & PRCI_COREPLL_DIVQ_MASK) >> PRCI_COREPLL_DIVQ_SHIFT;
-       divr = (val & PRCI_COREPLL_DIVR_MASK) >> PRCI_COREPLL_DIVR_SHIFT;
+       divf = (val & PRCI_PLL_DIVF_MASK) >> PRCI_PLL_DIVF_SHIFT;
+       divq = (val & PRCI_PLL_DIVQ_MASK) >> PRCI_PLL_DIVQ_SHIFT;
+       divr = (val & PRCI_PLL_DIVR_MASK) >> PRCI_PLL_DIVR_SHIFT;
 
        *freq = refclk / (divr + 1) * (2 * (divf + 1)) / (1 << divq);
 
@@ -160,7 +186,8 @@ prci_probe(device_t dev)
 }
 
 static void
-prci_pll_register(struct prci_softc *parent_sc, struct clknode_init_def 
*clkdef)
+prci_pll_register(struct prci_softc *parent_sc, struct clknode_init_def 
*clkdef,
+       uint32_t reg)
 {
        struct clknode *clk;
        struct prci_clk_pll_sc *sc;
@@ -172,6 +199,7 @@ prci_pll_register(struct prci_softc *parent_sc, struct
 
        sc = clknode_get_softc(clk);
        sc->parent_sc = parent_sc;
+       sc->reg = reg;
 
        clknode_register(parent_sc->clkdom, clk);
 }
@@ -207,8 +235,6 @@ prci_attach(device_t dev)
        }
 
        bzero(&clkdef, sizeof(clkdef));
-       clkdef.id = 0;
-       clkdef.name = "coreclk";
        clkdef.parent_names = mallocarray(ncells, sizeof(char *), M_OFWPROP,
            M_WAITOK);
        for (i = 0; i < ncells; i++) {
@@ -232,7 +258,11 @@ prci_attach(device_t dev)
        }
 
        /* We can't free a clkdom, so from now on we cannot fail. */
-       prci_pll_register(sc, &clkdef);
+       for (i = 0; i < nitems(pll_clks); i++) {
+               clkdef.id = pll_clks[i].id;
+               clkdef.name = pll_clks[i].name;
+               prci_pll_register(sc, &clkdef, pll_clks[i].reg);
+       }
 
        error = clkdom_finit(sc->clkdom);
        if (error)
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to