Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/rockchip Add support for RK3399 CPU clocks.
details: https://anonhg.NetBSD.org/src/rev/d4436e51ebd7
branches: trunk
changeset: 366540:d4436e51ebd7
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Sep 01 19:35:53 2018 +0000
description:
Add support for RK3399 CPU clocks.
diffstat:
sys/arch/arm/rockchip/rk3399_cru.c | 100 ++++++++++++++++++++++++++++++++---
sys/arch/arm/rockchip/rk_cru.h | 38 +++++++++++++-
sys/arch/arm/rockchip/rk_cru_arm.c | 101 ++++++++++++++++++++++++++++++++----
3 files changed, 215 insertions(+), 24 deletions(-)
diffs (truncated from 377 to 300 lines):
diff -r c635afb3b246 -r d4436e51ebd7 sys/arch/arm/rockchip/rk3399_cru.c
--- a/sys/arch/arm/rockchip/rk3399_cru.c Sat Sep 01 19:26:46 2018 +0000
+++ b/sys/arch/arm/rockchip/rk3399_cru.c Sat Sep 01 19:35:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3399_cru.c,v 1.2 2018/08/12 19:28:41 jmcneill Exp $ */
+/* $NetBSD: rk3399_cru.c,v 1.3 2018/09/01 19:35:53 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.2 2018/08/12 19:28:41 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.3 2018/09/01 19:35:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -139,6 +139,67 @@
static const struct rk_cru_pll_rate pll_norates[] = {
};
+#define RK3399_ACLKM_MASK __BITS(12,8)
+#define RK3399_ATCLK_MASK __BITS(4,0)
+#define RK3399_PDBG_MASK __BITS(12,8)
+
+#define RK3399_CPUL_RATE(_rate, _aclkm, _atclk, _pdbg) \
+ RK_CPU_RATE(_rate, \
+ CLKSEL_CON(0), RK3399_ACLKM_MASK, \
+ __SHIFTIN((_aclkm), RK3399_ACLKM_MASK), \
+ CLKSEL_CON(1), RK3399_ATCLK_MASK|RK3399_PDBG_MASK, \
+ __SHIFTIN((_atclk), RK3399_ATCLK_MASK)|__SHIFTIN((_pdbg), RK3399_PDBG_MASK))
+
+#define RK3399_CPUB_RATE(_rate, _aclkm, _atclk, _pdbg) \
+ RK_CPU_RATE(_rate, \
+ CLKSEL_CON(2), RK3399_ACLKM_MASK, \
+ __SHIFTIN((_aclkm), RK3399_ACLKM_MASK), \
+ CLKSEL_CON(3), RK3399_ATCLK_MASK|RK3399_PDBG_MASK, \
+ __SHIFTIN((_atclk), RK3399_ATCLK_MASK)|__SHIFTIN((_pdbg), RK3399_PDBG_MASK))
+
+static const struct rk_cru_cpu_rate armclkl_rates[] = {
+ RK3399_CPUL_RATE(1800000000, 1, 8, 8),
+ RK3399_CPUL_RATE(1704000000, 1, 8, 8),
+ RK3399_CPUL_RATE(1608000000, 1, 7, 7),
+ RK3399_CPUL_RATE(1512000000, 1, 7, 7),
+ RK3399_CPUL_RATE(1488000000, 1, 6, 6),
+ RK3399_CPUL_RATE(1416000000, 1, 6, 6),
+ RK3399_CPUL_RATE(1200000000, 1, 5, 5),
+ RK3399_CPUL_RATE(1008000000, 1, 4, 4),
+ RK3399_CPUL_RATE( 816000000, 1, 3, 3),
+ RK3399_CPUL_RATE( 696000000, 1, 3, 3),
+ RK3399_CPUL_RATE( 600000000, 1, 2, 2),
+ RK3399_CPUL_RATE( 408000000, 1, 1, 1),
+ RK3399_CPUL_RATE( 312000000, 1, 1, 1),
+ RK3399_CPUL_RATE( 216000000, 1, 1, 1),
+ RK3399_CPUL_RATE( 96000000, 1, 1, 1),
+};
+
+static const struct rk_cru_cpu_rate armclkb_rates[] = {
+ RK3399_CPUB_RATE(2208000000, 1, 11, 11),
+ RK3399_CPUB_RATE(2184000000, 1, 11, 11),
+ RK3399_CPUB_RATE(2088000000, 1, 10, 10),
+ RK3399_CPUB_RATE(2040000000, 1, 10, 10),
+ RK3399_CPUB_RATE(2016000000, 1, 9, 9),
+ RK3399_CPUB_RATE(1992000000, 1, 9, 9),
+ RK3399_CPUB_RATE(1896000000, 1, 9, 9),
+ RK3399_CPUB_RATE(1800000000, 1, 8, 8),
+ RK3399_CPUB_RATE(1704000000, 1, 8, 8),
+ RK3399_CPUB_RATE(1608000000, 1, 7, 7),
+ RK3399_CPUB_RATE(1512000000, 1, 7, 7),
+ RK3399_CPUB_RATE(1488000000, 1, 6, 6),
+ RK3399_CPUB_RATE(1416000000, 1, 6, 6),
+ RK3399_CPUB_RATE(1200000000, 1, 5, 5),
+ RK3399_CPUB_RATE(1008000000, 1, 5, 5),
+ RK3399_CPUB_RATE( 816000000, 1, 4, 4),
+ RK3399_CPUB_RATE( 696000000, 1, 3, 3),
+ RK3399_CPUB_RATE( 600000000, 1, 3, 3),
+ RK3399_CPUB_RATE( 408000000, 1, 2, 2),
+ RK3399_CPUB_RATE( 312000000, 1, 1, 1),
+ RK3399_CPUB_RATE( 216000000, 1, 1, 1),
+ RK3399_CPUB_RATE( 96000000, 1, 1, 1),
+};
+
#define PLL_CON0 0x00
#define PLL_FBDIV __BITS(11,0)
@@ -229,14 +290,13 @@
CRU_WRITE(sc, pll->con_base + PLL_CON3, val);
CRU_WRITE(sc, pll->con_base + PLL_CON0,
- __SHIFTIN(pll_rate->fbdiv, PLL_FBDIV) |
- PLL_WRITE_MASK);
+ __SHIFTIN(pll_rate->fbdiv, PLL_FBDIV) | (PLL_FBDIV << 16));
CRU_WRITE(sc, pll->con_base + PLL_CON1,
__SHIFTIN(pll_rate->postdiv2, PLL_POSTDIV2) |
__SHIFTIN(pll_rate->postdiv1, PLL_POSTDIV1) |
__SHIFTIN(pll_rate->refdiv, PLL_REFDIV) |
- PLL_WRITE_MASK);
+ ((PLL_POSTDIV2 | PLL_POSTDIV1 | PLL_REFDIV) << 16));
val = CRU_READ(sc, pll->con_base + PLL_CON2);
val &= ~PLL_FRACDIV;
@@ -246,11 +306,6 @@
val = __SHIFTIN(pll_rate->dsmpd, PLL_DSMPD) | (PLL_DSMPD << 16);
CRU_WRITE(sc, pll->con_base + PLL_CON3, val);
- /* Set PLL work mode to normal */
- const uint32_t write_mask = pll->mode_mask << 16;
- const uint32_t write_val = pll->mode_mask;
- CRU_WRITE(sc, pll->mode_reg, write_mask | write_val);
-
for (retry = 1000; retry > 0; retry--) {
if (CRU_READ(sc, pll->con_base + PLL_CON2) & pll->lock_mask)
break;
@@ -261,6 +316,7 @@
device_printf(sc->sc_dev, "WARNING: %s failed to lock\n",
clk->base.name);
+ /* Set PLL work mode to normal */
val = __SHIFTIN(PLL_WORK_MODE_NORMAL, PLL_WORK_MODE) | (PLL_WORK_MODE << 16);
CRU_WRITE(sc, pll->con_base + PLL_CON3, val);
@@ -287,6 +343,8 @@
}
static const char * pll_parents[] = { "xin24m", "xin32k" };
+static const char * armclkl_parents[] = { "clk_core_l_lpll_src", "clk_core_l_bpll_src", "clk_core_l_dpll_src", "clk_core_l_gpll_src" };
+static const char * armclkb_parents[] = { "clk_core_b_lpll_src", "clk_core_b_bpll_src", "clk_core_b_dpll_src", "clk_core_b_gpll_src" };
static const char * mux_pll_src_cpll_gpll_parents[] = { "cpll", "gpll" };
static const char * mux_pll_src_cpll_gpll_npll_parents[] = { "cpll", "gpll", "npll" };
static const char * mux_pll_src_cpll_gpll_upll_parents[] = { "cpll", "gpll", "upll" };
@@ -346,6 +404,28 @@
__BIT(31), /* lock_mask */
pll_rates),
+ RK_GATE(0, "clk_core_l_lpll_src", "lpll", CLKGATE_CON(0), 0),
+ RK_GATE(0, "clk_core_l_bpll_src", "bpll", CLKGATE_CON(0), 1),
+ RK_GATE(0, "clk_core_l_dpll_src", "dpll", CLKGATE_CON(0), 2),
+ RK_GATE(0, "clk_core_l_gpll_src", "gpll", CLKGATE_CON(0), 3),
+
+ RK_CPU(RK3399_ARMCLKL, "armclkl", armclkl_parents,
+ CLKSEL_CON(0), /* reg */
+ __BITS(7,6), 0, 3, /* mux_mask, mux_main, mux_alt */
+ __BITS(4,0), /* div_mask */
+ armclkl_rates),
+
+ RK_GATE(0, "clk_core_b_lpll_src", "lpll", CLKGATE_CON(1), 0),
+ RK_GATE(0, "clk_core_b_bpll_src", "bpll", CLKGATE_CON(1), 1),
+ RK_GATE(0, "clk_core_b_dpll_src", "dpll", CLKGATE_CON(1), 2),
+ RK_GATE(0, "clk_core_b_gpll_src", "gpll", CLKGATE_CON(1), 3),
+
+ RK_CPU(RK3399_ARMCLKB, "armclkb", armclkb_parents,
+ CLKSEL_CON(2), /* reg */
+ __BITS(7,6), 1, 3, /* mux_mask, mux_main, mux_alt */
+ __BITS(4,0), /* div_mask */
+ armclkb_rates),
+
/*
* perilp0
*/
diff -r c635afb3b246 -r d4436e51ebd7 sys/arch/arm/rockchip/rk_cru.h
--- a/sys/arch/arm/rockchip/rk_cru.h Sat Sep 01 19:26:46 2018 +0000
+++ b/sys/arch/arm/rockchip/rk_cru.h Sat Sep 01 19:35:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru.h,v 1.3 2018/08/12 16:48:05 jmcneill Exp $ */
+/* $NetBSD: rk_cru.h,v 1.4 2018/09/01 19:35:53 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -118,6 +118,19 @@
.div = (_div), \
}
+struct rk_cru_cpu_rate {
+ u_int rate;
+ u_int reg1, reg1_mask, reg1_val;
+ u_int reg2, reg2_mask, reg2_val;
+};
+
+#define RK_CPU_RATE(_rate, _reg1, _reg1_mask, _reg1_val, _reg2, _reg2_mask, _reg2_val) \
+ { \
+ .rate = (_rate), \
+ .reg1 = (_reg1), .reg1_mask = (_reg1_mask), .reg1_val = (_reg1_val), \
+ .reg2 = (_reg2), .reg2_mask = (_reg2_mask), .reg2_val = (_reg2_val), \
+ }
+
struct rk_cru_arm {
bus_size_t reg;
uint32_t mux_mask;
@@ -127,11 +140,13 @@
const char **parents;
u_int nparents;
const struct rk_cru_arm_rate *rates;
+ const struct rk_cru_cpu_rate *cpurates;
u_int nrates;
};
u_int rk_cru_arm_get_rate(struct rk_cru_softc *, struct rk_cru_clk *);
int rk_cru_arm_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int);
+int rk_cru_arm_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int);
const char *rk_cru_arm_get_parent(struct rk_cru_softc *, struct rk_cru_clk *);
int rk_cru_arm_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *);
@@ -156,6 +171,27 @@
.set_parent = rk_cru_arm_set_parent, \
}
+#define RK_CPU(_id, _name, _parents, _reg, _mux_mask, _mux_main, _mux_alt, _div_mask, _cpurates) \
+ { \
+ .id = (_id), \
+ .type = RK_CRU_ARM, \
+ .base.name = (_name), \
+ .base.flags = 0, \
+ .u.arm.parents = (_parents), \
+ .u.arm.nparents = __arraycount(_parents), \
+ .u.arm.reg = (_reg), \
+ .u.arm.mux_mask = (_mux_mask), \
+ .u.arm.mux_main = (_mux_main), \
+ .u.arm.mux_alt = (_mux_alt), \
+ .u.arm.div_mask = (_div_mask), \
+ .u.arm.cpurates = (_cpurates), \
+ .u.arm.nrates = __arraycount(_cpurates), \
+ .get_rate = rk_cru_arm_get_rate, \
+ .set_rate = rk_cru_arm_set_rate, \
+ .get_parent = rk_cru_arm_get_parent, \
+ .set_parent = rk_cru_arm_set_parent, \
+ }
+
/* Composite clocks */
struct rk_cru_composite {
diff -r c635afb3b246 -r d4436e51ebd7 sys/arch/arm/rockchip/rk_cru_arm.c
--- a/sys/arch/arm/rockchip/rk_cru_arm.c Sat Sep 01 19:26:46 2018 +0000
+++ b/sys/arch/arm/rockchip/rk_cru_arm.c Sat Sep 01 19:35:53 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru_arm.c,v 1.1 2018/06/16 00:19:04 jmcneill Exp $ */
+/* $NetBSD: rk_cru_arm.c,v 1.2 2018/09/01 19:35:53 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_cru_arm.c,v 1.1 2018/06/16 00:19:04 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_cru_arm.c,v 1.2 2018/09/01 19:35:53 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -60,13 +60,13 @@
return fref / div;
}
-int
-rk_cru_arm_set_rate(struct rk_cru_softc *sc,
+static int
+rk_cru_arm_set_rate_rates(struct rk_cru_softc *sc,
struct rk_cru_clk *clk, u_int rate)
{
struct rk_cru_arm *arm = &clk->u.arm;
+ struct rk_cru_clk *main_parent, *alt_parent;
const struct rk_cru_arm_rate *arm_rate = NULL;
- struct clk *clkp_parent;
int error;
KASSERT(clk->type == RK_CRU_ARM);
@@ -82,26 +82,101 @@
if (arm_rate == NULL)
return EINVAL;
- error = rk_cru_arm_set_parent(sc, clk, arm->parents[arm->mux_main]);
+ main_parent = rk_cru_clock_find(sc, arm->parents[arm->mux_main]);
+ alt_parent = rk_cru_clock_find(sc, arm->parents[arm->mux_alt]);
+ if (main_parent == NULL || alt_parent == NULL) {
+ device_printf(sc->sc_dev, "couldn't get clock parents\n");
+ return ENXIO;
+ }
+
+ error = rk_cru_arm_set_parent(sc, clk, arm->parents[arm->mux_alt]);
if (error != 0)
return error;
- clkp_parent = clk_get_parent(&clk->base);
- if (clkp_parent == NULL)
- return ENXIO;
-
const u_int parent_rate = arm_rate->rate / arm_rate->div;
- error = clk_set_rate(clkp_parent, parent_rate);
+ error = clk_set_rate(&main_parent->base, parent_rate);
if (error != 0)
- return error;
+ goto done;
const uint32_t write_mask = arm->div_mask << 16;
const uint32_t write_val = __SHIFTIN(arm_rate->div - 1, arm->div_mask);
CRU_WRITE(sc, arm->reg, write_mask | write_val);
Home |
Main Index |
Thread Index |
Old Index