Module Name:    src
Committed By:   jmcneill
Date:           Sun Nov 10 11:43:04 UTC 2019

Modified Files:
        src/sys/arch/arm/rockchip: rk3399_cru.c rk_cru.h rk_cru_composite.c

Log Message:
Force DCLK_VOP0/1 dividers to 1 and select closest match when setting PLL
rates.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/rockchip/rk3399_cru.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/rockchip/rk_cru.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/rockchip/rk_cru_composite.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/rockchip/rk3399_cru.c
diff -u src/sys/arch/arm/rockchip/rk3399_cru.c:1.11 src/sys/arch/arm/rockchip/rk3399_cru.c:1.12
--- src/sys/arch/arm/rockchip/rk3399_cru.c:1.11	Sat Nov  9 23:29:48 2019
+++ src/sys/arch/arm/rockchip/rk3399_cru.c	Sun Nov 10 11:43:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3399_cru.c,v 1.11 2019/11/09 23:29:48 jmcneill Exp $ */
+/* $NetBSD: rk3399_cru.c,v 1.12 2019/11/10 11:43:04 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.11 2019/11/09 23:29:48 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.12 2019/11/10 11:43:04 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -271,20 +271,21 @@ rk3399_cru_pll_set_rate(struct rk_cru_so
 	struct rk_cru_pll *pll = &clk->u.pll;
 	const struct rk_cru_pll_rate *pll_rate = NULL;
 	uint32_t val;
-	int retry;
+	int retry, best_diff;
 
 	KASSERT(clk->type == RK_CRU_PLL);
 
 	if (pll->rates == NULL || rate == 0)
 		return EIO;
 
-	for (int i = 0; i < pll->nrates; i++)
-		if (pll->rates[i].rate == rate) {
+	best_diff = INT_MAX;
+	for (int i = 0; i < pll->nrates; i++) {
+		const int diff = (int)rate - (int)pll->rates[i].rate;
+		if (abs(diff) < best_diff) {
 			pll_rate = &pll->rates[i];
-			break;
+			best_diff = abs(diff);
 		}
-	if (pll_rate == NULL)
-		return EINVAL;
+	}
 
 	val = __SHIFTIN(PLL_WORK_MODE_SLOW, PLL_WORK_MODE) | (PLL_WORK_MODE << 16);
 	CRU_WRITE(sc, pll->con_base + PLL_CON3, val);
@@ -869,7 +870,7 @@ static struct rk_cru_clk rk3399_cru_clks
 		     __BITS(7,0),	/* div_mask */
 		     CLKGATE_CON(10),	/* gate_reg */
 		     __BIT(12),		/* gate_mask */
-		     0),
+		     RK_COMPOSITE_SET_RATE_PARENT),
 	RK_GATE(RK3399_ACLK_VOP0, "aclk_vop0", "aclk_vop0_pre", CLKGATE_CON(28), 3),
 	RK_GATE(RK3399_HCLK_VOP0, "hclk_vop0", "hclk_vop0_pre", CLKGATE_CON(28), 2),
 	RK_MUX(RK3399_DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_parents, CLKSEL_CON(49), __BIT(11)),
@@ -894,7 +895,7 @@ static struct rk_cru_clk rk3399_cru_clks
 		     __BITS(7,0),	/* div_mask */
 		     CLKGATE_CON(10),	/* gate_reg */
 		     __BIT(13),		/* gate_mask */
-		     0),
+		     RK_COMPOSITE_SET_RATE_PARENT),
 	RK_GATE(RK3399_ACLK_VOP1, "aclk_vop1", "aclk_vop1_pre", CLKGATE_CON(28), 7),
 	RK_GATE(RK3399_HCLK_VOP1, "hclk_vop1", "hclk_vop1_pre", CLKGATE_CON(28), 6),
 	RK_MUX(RK3399_DCLK_VOP1, "dclk_vop1", mux_dclk_vop1_parents, CLKSEL_CON(50), __BIT(11)),
@@ -944,12 +945,21 @@ static void
 rk3399_cru_init(struct rk_cru_softc *sc)
 {
 	struct rk_cru_clk *clk;
+	uint32_t write_mask, write_val;
 
 	/*
 	 * Force an update of BPLL to bring it out of slow mode.
 	 */
 	clk = rk_cru_clock_find(sc, "armclkb");
 	clk_set_rate(&clk->base, clk_get_rate(&clk->base));
+
+	/*
+	 * Set DCLK_VOP0 and DCLK_VOP1 dividers to 1.
+	 */
+	write_mask = __BITS(7,0) << 16;
+	write_val = 0;
+	CRU_WRITE(sc, CLKSEL_CON(49), write_mask | write_val);
+	CRU_WRITE(sc, CLKSEL_CON(50), write_mask | write_val);
 }
 
 static int

Index: src/sys/arch/arm/rockchip/rk_cru.h
diff -u src/sys/arch/arm/rockchip/rk_cru.h:1.5 src/sys/arch/arm/rockchip/rk_cru.h:1.6
--- src/sys/arch/arm/rockchip/rk_cru.h:1.5	Sat Oct 19 12:55:21 2019
+++ src/sys/arch/arm/rockchip/rk_cru.h	Sun Nov 10 11:43:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru.h,v 1.5 2019/10/19 12:55:21 tnn Exp $ */
+/* $NetBSD: rk_cru.h,v 1.6 2019/11/10 11:43:04 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -204,6 +204,7 @@ struct rk_cru_composite {
 	u_int		nparents;
 	u_int		flags;
 #define	RK_COMPOSITE_ROUND_DOWN		0x01
+#define	RK_COMPOSITE_SET_RATE_PARENT	0x02
 };
 
 int	rk_cru_composite_enable(struct rk_cru_softc *, struct rk_cru_clk *, int);

Index: src/sys/arch/arm/rockchip/rk_cru_composite.c
diff -u src/sys/arch/arm/rockchip/rk_cru_composite.c:1.3 src/sys/arch/arm/rockchip/rk_cru_composite.c:1.4
--- src/sys/arch/arm/rockchip/rk_cru_composite.c:1.3	Tue Jun 19 01:24:17 2018
+++ src/sys/arch/arm/rockchip/rk_cru_composite.c	Sun Nov 10 11:43:04 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru_composite.c,v 1.3 2018/06/19 01:24:17 jmcneill Exp $ */
+/* $NetBSD: rk_cru_composite.c,v 1.4 2019/11/10 11:43:04 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_cru_composite.c,v 1.3 2018/06/19 01:24:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_cru_composite.c,v 1.4 2019/11/10 11:43:04 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -92,6 +92,13 @@ rk_cru_composite_set_rate(struct rk_cru_
 
 	KASSERT(clk->type == RK_CRU_COMPOSITE);
 
+	if (composite->flags & RK_COMPOSITE_SET_RATE_PARENT) {
+		clk_parent = clk_get_parent(&clk->base);
+		if (clk_parent == NULL)
+			return ENXIO;
+		return clk_set_rate(clk_parent, rate);
+	}
+
 	best_div = 0;
 	best_mux = 0;
 	best_diff = INT_MAX;

Reply via email to