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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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;