Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Feb 2020 17:09:56 +0000 (UTC)
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r357369 - head/sys/riscv/sifive
Message-ID:  <202002011709.011H9ukr026990@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002011709.011H9ukr026990>