Module Name: src
Committed By: jmcneill
Date: Wed Jun 10 17:57:50 UTC 2020
Modified Files:
src/sys/arch/arm/imx/fdt: files.imx6 imx6_clk.c imx_ccm.c imx_ccm.h
imx_ccm_composite.c imx_ccm_gate.c
src/sys/arch/evbarm/conf: GENERIC
Added Files:
src/sys/arch/arm/imx/fdt: imx7_platform.c imx7_platform.h imx7d_ccm.c
imx7d_ccm.h imx_ccm_div.c imx_ccm_mux.c imx_ccm_pll.c
Log Message:
FDT-ize i.MX7. I don't have a board so this has only been tested on QEMU.
To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/imx/fdt/files.imx6
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/fdt/imx6_clk.c \
src/sys/arch/arm/imx/fdt/imx_ccm.c src/sys/arch/arm/imx/fdt/imx_ccm.h \
src/sys/arch/arm/imx/fdt/imx_ccm_composite.c \
src/sys/arch/arm/imx/fdt/imx_ccm_gate.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/fdt/imx7_platform.c \
src/sys/arch/arm/imx/fdt/imx7_platform.h \
src/sys/arch/arm/imx/fdt/imx7d_ccm.c src/sys/arch/arm/imx/fdt/imx7d_ccm.h \
src/sys/arch/arm/imx/fdt/imx_ccm_div.c \
src/sys/arch/arm/imx/fdt/imx_ccm_mux.c \
src/sys/arch/arm/imx/fdt/imx_ccm_pll.c
cvs rdiff -u -r1.79 -r1.80 src/sys/arch/evbarm/conf/GENERIC
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/imx/fdt/files.imx6
diff -u src/sys/arch/arm/imx/fdt/files.imx6:1.12 src/sys/arch/arm/imx/fdt/files.imx6:1.13
--- src/sys/arch/arm/imx/fdt/files.imx6:1.12 Wed Jun 3 13:14:01 2020
+++ src/sys/arch/arm/imx/fdt/files.imx6 Wed Jun 10 17:57:50 2020
@@ -1,30 +1,40 @@
-# $NetBSD: files.imx6,v 1.12 2020/06/03 13:14:01 jmcneill Exp $
+# $NetBSD: files.imx6,v 1.13 2020/06/10 17:57:50 jmcneill Exp $
#
# Configuration info for the Freescale i.MX6
#
file arch/arm/imx/fdt/imx6_platform.c soc_imx
+file arch/arm/imx/fdt/imx7_platform.c soc_imx
# SOC parameters
defflag opt_soc.h SOC_IMX
defflag opt_soc.h SOC_IMX6DL: SOC_IMX
defflag opt_soc.h SOC_IMX6Q: SOC_IMX
defflag opt_soc.h SOC_IMX6QDL: SOC_IMX
+defflag opt_soc.h SOC_IMX7D: SOC_IMX
# Clock
-device imxccm: clk
-attach imxccm at fdt
-file arch/arm/imx/imx6_ccm.c imxccm
-file arch/arm/imx/fdt/imx6_clk.c imxccm
+device imx6ccm: clk
+attach imx6ccm at fdt
+file arch/arm/imx/imx6_ccm.c imx6ccm
+file arch/arm/imx/fdt/imx6_clk.c imx6ccm
# Common FDT clock framework
define imx_ccm: clk
file arch/arm/imx/fdt/imx_ccm.c imx_ccm
-file arch/arm/imx/fdt/imx_ccm_extclk.c imx_ccm
-file arch/arm/imx/fdt/imx_ccm_gate.c imx_ccm
file arch/arm/imx/fdt/imx_ccm_composite.c imx_ccm
+file arch/arm/imx/fdt/imx_ccm_div.c imx_ccm
+file arch/arm/imx/fdt/imx_ccm_extclk.c imx_ccm
file arch/arm/imx/fdt/imx_ccm_fixed.c imx_ccm
file arch/arm/imx/fdt/imx_ccm_fixed_factor.c imx_ccm
+file arch/arm/imx/fdt/imx_ccm_gate.c imx_ccm
+file arch/arm/imx/fdt/imx_ccm_mux.c imx_ccm
+file arch/arm/imx/fdt/imx_ccm_pll.c imx_ccm
+
+# CCM (iMX7D)
+device imx7dccm: imx_ccm
+attach imx7dccm at fdt with imx7d_ccm
+file arch/arm/imx/fdt/imx7d_ccm.c imx7d_ccm
# CCM (iMX8MQ)
device imx8mqccm: imx_ccm
Index: src/sys/arch/arm/imx/fdt/imx6_clk.c
diff -u src/sys/arch/arm/imx/fdt/imx6_clk.c:1.1 src/sys/arch/arm/imx/fdt/imx6_clk.c:1.2
--- src/sys/arch/arm/imx/fdt/imx6_clk.c:1.1 Wed Jul 24 13:12:33 2019
+++ src/sys/arch/arm/imx/fdt/imx6_clk.c Wed Jun 10 17:57:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: imx6_clk.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $ */
+/* $NetBSD: imx6_clk.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Genetec Corporation. All rights reserved.
* Written by Hashimoto Kenichi for Genetec Corporation.
@@ -25,7 +25,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_clk.c,v 1.1 2019/07/24 13:12:33 hkenken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_clk.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $");
#include "opt_fdt.h"
@@ -86,7 +86,7 @@ imx6_clk_fixed_from_fdt(const char *name
static int imxccm_match(device_t, cfdata_t, void *);
static void imxccm_attach(device_t, device_t, void *);
-CFATTACH_DECL_NEW(imxccm, sizeof(struct imxccm_softc),
+CFATTACH_DECL_NEW(imx6ccm, sizeof(struct imxccm_softc),
imxccm_match, imxccm_attach, NULL, NULL);
static int
Index: src/sys/arch/arm/imx/fdt/imx_ccm.c
diff -u src/sys/arch/arm/imx/fdt/imx_ccm.c:1.1 src/sys/arch/arm/imx/fdt/imx_ccm.c:1.2
--- src/sys/arch/arm/imx/fdt/imx_ccm.c:1.1 Wed Jan 15 01:09:56 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm.c Wed Jun 10 17:57:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: imx_ccm.c,v 1.1 2020/01/15 01:09:56 jmcneill Exp $ */
+/* $NetBSD: imx_ccm.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx_ccm.c,v 1.1 2020/01/15 01:09:56 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx_ccm.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -215,7 +215,7 @@ imx_ccm_clock_get_parent(void *priv, str
return fdtbus_clock_byname(parent);
}
-static const struct clk_funcs imx_ccm_clock_funcs = {
+const struct clk_funcs imx_ccm_clock_funcs = {
.get = imx_ccm_clock_get,
.put = imx_ccm_clock_put,
.get_rate = imx_ccm_clock_get_rate,
@@ -251,7 +251,7 @@ imx_ccm_attach(struct imx_ccm_softc *sc)
aprint_error(": couldn't get registers\n");
return ENXIO;
}
- if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+ if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh[0]) != 0) {
aprint_error(": couldn't map registers\n");
return ENXIO;
}
@@ -289,8 +289,11 @@ imx_ccm_print(struct imx_ccm_softc *sc)
case IMX_CCM_EXTCLK: type = "extclk"; break;
case IMX_CCM_GATE: type = "gate"; break;
case IMX_CCM_COMPOSITE: type = "comp"; break;
+ case IMX_CCM_PLL: type = "pll"; break;
case IMX_CCM_FIXED: type = "fixed"; break;
case IMX_CCM_FIXED_FACTOR: type = "fixed-factor"; break;
+ case IMX_CCM_MUX: type = "mux"; break;
+ case IMX_CCM_DIV: type = "div"; break;
default: type = "???"; break;
}
Index: src/sys/arch/arm/imx/fdt/imx_ccm.h
diff -u src/sys/arch/arm/imx/fdt/imx_ccm.h:1.1 src/sys/arch/arm/imx/fdt/imx_ccm.h:1.2
--- src/sys/arch/arm/imx/fdt/imx_ccm.h:1.1 Wed Jan 15 01:09:56 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm.h Wed Jun 10 17:57:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: imx_ccm.h,v 1.1 2020/01/15 01:09:56 jmcneill Exp $ */
+/* $NetBSD: imx_ccm.h,v 1.2 2020/06/10 17:57:50 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <[email protected]>
@@ -44,8 +44,11 @@ enum imx_ccm_clktype {
IMX_CCM_EXTCLK,
IMX_CCM_GATE,
IMX_CCM_COMPOSITE,
+ IMX_CCM_PLL,
IMX_CCM_FIXED,
IMX_CCM_FIXED_FACTOR,
+ IMX_CCM_MUX,
+ IMX_CCM_DIV,
};
/* External clocks */
@@ -81,9 +84,12 @@ int imx_ccm_gate_enable(struct imx_ccm_s
const char *imx_ccm_gate_get_parent(struct imx_ccm_softc *,
struct imx_ccm_clk *);
-#define IMX_GATE(_id, _name, _pname, _reg, _mask) \
+#define IMX_GATE(_id, _name, _pname, _reg, _mask) \
+ IMX_GATE_INDEX(_id, 0, _name, _pname, _reg, _mask)
+#define IMX_GATE_INDEX(_id, _regidx, _name, _pname, _reg, _mask) \
{ \
.id = (_id), \
+ .regidx = (_regidx), \
.type = IMX_CCM_GATE, \
.base.name = (_name), \
.base.flags = CLK_SET_RATE_PARENT, \
@@ -94,7 +100,9 @@ const char *imx_ccm_gate_get_parent(stru
.get_parent = imx_ccm_gate_get_parent, \
}
#define IMX_ROOT_GATE(_id, _name, _pname, _reg) \
- IMX_GATE(_id, _name, _pname, _reg, __BITS(1,0))
+ IMX_ROOT_GATE_INDEX(_id, 0, _name, _pname, _reg)
+#define IMX_ROOT_GATE_INDEX(_id, _regidx, _name, _pname, _reg) \
+ IMX_GATE_INDEX(_id, _regidx, _name, _pname, _reg, __BITS(1,0))
/* Composite clocks */
@@ -114,8 +122,12 @@ const char *imx_ccm_composite_get_parent
int imx_ccm_composite_set_parent(struct imx_ccm_softc *, struct imx_ccm_clk *, const char *);
#define IMX_COMPOSITE(_id, _name, _parents, _reg, _flags) \
+ IMX_COMPOSITE_INDEX(_id, 0, _name, _parents, _reg, _flags)
+
+#define IMX_COMPOSITE_INDEX(_id, _regidx, _name, _parents, _reg, _flags) \
{ \
.id = (_id), \
+ .regidx = (_regidx), \
.type = IMX_CCM_COMPOSITE, \
.base.name = (_name), \
.base.flags = 0, \
@@ -130,6 +142,40 @@ int imx_ccm_composite_set_parent(struct
.get_parent = imx_ccm_composite_get_parent, \
}
+/* PLLs */
+
+struct imx_ccm_pll {
+ bus_size_t reg;
+ const char *parent;
+ uint32_t div_mask;
+ u_int flags;
+#define IMX_PLL_ARM __BIT(0)
+#define IMX_PLL_480M_528M __BIT(1)
+#define IMX_PLL_ENET __BIT(2)
+};
+
+int imx_ccm_pll_enable(struct imx_ccm_softc *, struct imx_ccm_clk *, int);
+u_int imx_ccm_pll_get_rate(struct imx_ccm_softc *, struct imx_ccm_clk *);
+const char *imx_ccm_pll_get_parent(struct imx_ccm_softc *, struct imx_ccm_clk *);
+
+#define IMX_PLL(_id, _name, _parent, _reg, _div_mask, _flags) \
+ IMX_PLL_INDEX(_id, 0, _name, _parent, _reg, _div_mask, _flags)
+#define IMX_PLL_INDEX(_id, _regidx, _name, _parent, _reg, _div_mask, _flags) \
+ { \
+ .id = (_id), \
+ .regidx = (_regidx), \
+ .type = IMX_CCM_PLL, \
+ .base.name = (_name), \
+ .base.flags = 0, \
+ .u.pll.parent = (_parent), \
+ .u.pll.reg = (_reg), \
+ .u.pll.div_mask = (_div_mask), \
+ .u.pll.flags = (_flags), \
+ .enable = imx_ccm_pll_enable, \
+ .get_rate = imx_ccm_pll_get_rate, \
+ .get_parent = imx_ccm_pll_get_parent, \
+ }
+
/* Fixed clocks */
struct imx_ccm_fixed {
@@ -174,6 +220,69 @@ const char *imx_ccm_fixed_factor_get_par
.get_parent = imx_ccm_fixed_factor_get_parent, \
}
+/* Mux clocks */
+
+struct imx_ccm_mux {
+ bus_size_t reg;
+ const char **parents;
+ u_int nparents;
+ uint32_t sel;
+};
+
+const char *imx_ccm_mux_get_parent(struct imx_ccm_softc *, struct imx_ccm_clk *);
+int imx_ccm_mux_set_parent(struct imx_ccm_softc *, struct imx_ccm_clk *, const char *);
+
+#define IMX_MUX(_id, _name, _parents, _reg, _sel) \
+ IMX_MUX_INDEX(_id, 0, _name, _parents, _reg, _sel)
+
+#define IMX_MUX_INDEX(_id, _regidx, _name, _parents, _reg, _sel) \
+ { \
+ .id = (_id), \
+ .regidx = (_regidx), \
+ .type = IMX_CCM_MUX, \
+ .base.name = (_name), \
+ .base.flags = CLK_SET_RATE_PARENT, \
+ .u.mux.parents = (_parents), \
+ .u.mux.nparents = __arraycount(_parents), \
+ .u.mux.reg = (_reg), \
+ .u.mux.sel = (_sel), \
+ .get_parent = imx_ccm_mux_get_parent, \
+ .set_parent = imx_ccm_mux_set_parent, \
+ }
+
+/* Divider clocks */
+
+struct imx_ccm_div {
+ bus_size_t reg;
+ const char *parent;
+ uint32_t mask;
+ u_int flags;
+#define IMX_DIV_SET_RATE_PARENT __BIT(0)
+#define IMX_DIV_ROUND_DOWN __BIT(1)
+};
+
+u_int imx_ccm_div_get_rate(struct imx_ccm_softc *, struct imx_ccm_clk *);
+int imx_ccm_div_set_rate(struct imx_ccm_softc *, struct imx_ccm_clk *, u_int);
+const char *imx_ccm_div_get_parent(struct imx_ccm_softc *, struct imx_ccm_clk *);
+
+#define IMX_DIV(_id, _name, _parent, _reg, _mask, _flags) \
+ IMX_DIV_INDEX(_id, 0, _name, _parent, _reg, _mask, _flags)
+#define IMX_DIV_INDEX(_id, _regidx, _name, _parent, _reg, _mask, _flags) \
+ { \
+ .id = (_id), \
+ .regidx = (_regidx), \
+ .type = IMX_CCM_DIV, \
+ .base.name = (_name), \
+ .base.flags = 0, \
+ .u.div.parent = (_parent), \
+ .u.div.reg = (_reg), \
+ .u.div.mask = (_mask), \
+ .u.div.flags = (_flags), \
+ .get_rate = imx_ccm_div_get_rate, \
+ .set_rate = imx_ccm_div_set_rate, \
+ .get_parent = imx_ccm_div_get_parent, \
+ }
+
/*
* IMX clock definition
*/
@@ -181,12 +290,16 @@ const char *imx_ccm_fixed_factor_get_par
struct imx_ccm_clk {
struct clk base;
u_int id;
+ u_int regidx;
enum imx_ccm_clktype type;
union {
struct imx_ccm_gate gate;
struct imx_ccm_composite composite;
+ struct imx_ccm_pll pll;
struct imx_ccm_fixed fixed;
struct imx_ccm_fixed_factor fixed_factor;
+ struct imx_ccm_mux mux;
+ struct imx_ccm_div div;
const char *extclk;
} u;
@@ -213,7 +326,9 @@ struct imx_ccm_softc {
device_t sc_dev;
int sc_phandle;
bus_space_tag_t sc_bst;
- bus_space_handle_t sc_bsh;
+ bus_space_handle_t sc_bsh[2];
+
+ bus_addr_t sc_baseaddr;
struct clk_domain sc_clkdom;
@@ -226,9 +341,11 @@ struct imx_ccm_clk *imx_ccm_clock_find(s
const char *);
void imx_ccm_print(struct imx_ccm_softc *);
-#define CCM_READ(sc, reg) \
- bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
-#define CCM_WRITE(sc, reg, val) \
- bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+extern const struct clk_funcs imx_ccm_clock_funcs;
+
+#define CCM_READ(sc, idx, reg) \
+ bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh[idx], (reg))
+#define CCM_WRITE(sc, idx, reg, val) \
+ bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh[idx], (reg), (val))
#endif /* _ARM_IMX_CCM_H */
Index: src/sys/arch/arm/imx/fdt/imx_ccm_composite.c
diff -u src/sys/arch/arm/imx/fdt/imx_ccm_composite.c:1.1 src/sys/arch/arm/imx/fdt/imx_ccm_composite.c:1.2
--- src/sys/arch/arm/imx/fdt/imx_ccm_composite.c:1.1 Wed Jan 15 01:09:56 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm_composite.c Wed Jun 10 17:57:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: imx_ccm_composite.c,v 1.1 2020/01/15 01:09:56 jmcneill Exp $ */
+/* $NetBSD: imx_ccm_composite.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx_ccm_composite.c,v 1.1 2020/01/15 01:09:56 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx_ccm_composite.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -53,12 +53,12 @@ imx_ccm_composite_enable(struct imx_ccm_
KASSERT(clk->type == IMX_CCM_COMPOSITE);
- val = CCM_READ(sc, composite->reg + CCM_TARGET_ROOT);
+ val = CCM_READ(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT);
if (enable)
val |= TARGET_ROOT_ENABLE;
else
val &= ~TARGET_ROOT_ENABLE;
- CCM_WRITE(sc, composite->reg + CCM_TARGET_ROOT, val);
+ CCM_WRITE(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT, val);
return 0;
}
@@ -81,7 +81,7 @@ imx_ccm_composite_get_rate(struct imx_cc
if (prate == 0)
return 0;
- const uint32_t val = CCM_READ(sc, composite->reg + CCM_TARGET_ROOT);
+ const uint32_t val = CCM_READ(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT);
const u_int pre_div = __SHIFTOUT(val, TARGET_ROOT_PRE_PODF) + 1;
const u_int post_div = __SHIFTOUT(val, TARGET_ROOT_POST_PODF) + 1;
@@ -111,7 +111,7 @@ imx_ccm_composite_set_rate(struct imx_cc
best_postdiv = 0;
best_diff = INT_MAX;
- val = CCM_READ(sc, composite->reg + CCM_TARGET_ROOT);
+ val = CCM_READ(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT);
const u_int mux = __SHIFTOUT(val, TARGET_ROOT_MUX);
if (mux >= composite->nparents)
@@ -151,12 +151,12 @@ imx_ccm_composite_set_rate(struct imx_cc
if (best_diff == INT_MAX)
return ERANGE;
- val = CCM_READ(sc, composite->reg + CCM_TARGET_ROOT);
+ val = CCM_READ(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT);
val &= ~TARGET_ROOT_PRE_PODF;
val |= __SHIFTIN(best_prediv - 1, TARGET_ROOT_PRE_PODF);
val &= ~TARGET_ROOT_POST_PODF;
val |= __SHIFTIN(best_postdiv - 1, TARGET_ROOT_POST_PODF);
- CCM_WRITE(sc, composite->reg + CCM_TARGET_ROOT, val);
+ CCM_WRITE(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT, val);
return 0;
}
@@ -169,7 +169,7 @@ imx_ccm_composite_get_parent(struct imx_
KASSERT(clk->type == IMX_CCM_COMPOSITE);
- const uint32_t val = CCM_READ(sc, composite->reg + CCM_TARGET_ROOT);
+ const uint32_t val = CCM_READ(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT);
const u_int mux = __SHIFTOUT(val, TARGET_ROOT_MUX);
if (mux >= composite->nparents)
@@ -189,10 +189,10 @@ imx_ccm_composite_set_parent(struct imx_
for (u_int mux = 0; mux < composite->nparents; mux++) {
if (strcmp(composite->parents[mux], parent) == 0) {
- val = CCM_READ(sc, composite->reg + CCM_TARGET_ROOT);
+ val = CCM_READ(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT);
val &= ~TARGET_ROOT_MUX;
val |= __SHIFTIN(mux, TARGET_ROOT_MUX);
- CCM_WRITE(sc, composite->reg + CCM_TARGET_ROOT, val);
+ CCM_WRITE(sc, clk->regidx, composite->reg + CCM_TARGET_ROOT, val);
return 0;
}
}
Index: src/sys/arch/arm/imx/fdt/imx_ccm_gate.c
diff -u src/sys/arch/arm/imx/fdt/imx_ccm_gate.c:1.1 src/sys/arch/arm/imx/fdt/imx_ccm_gate.c:1.2
--- src/sys/arch/arm/imx/fdt/imx_ccm_gate.c:1.1 Wed Jan 15 01:09:57 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm_gate.c Wed Jun 10 17:57:50 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: imx_ccm_gate.c,v 1.1 2020/01/15 01:09:57 jmcneill Exp $ */
+/* $NetBSD: imx_ccm_gate.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx_ccm_gate.c,v 1.1 2020/01/15 01:09:57 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx_ccm_gate.c,v 1.2 2020/06/10 17:57:50 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -45,12 +45,12 @@ imx_ccm_gate_enable(struct imx_ccm_softc
KASSERT(clk->type == IMX_CCM_GATE);
- val = CCM_READ(sc, gate->reg);
+ val = CCM_READ(sc, clk->regidx, gate->reg);
if (enable)
val |= gate->mask;
else
val &= ~gate->mask;
- CCM_WRITE(sc, gate->reg, val);
+ CCM_WRITE(sc, clk->regidx, gate->reg, val);
return 0;
}
Index: src/sys/arch/evbarm/conf/GENERIC
diff -u src/sys/arch/evbarm/conf/GENERIC:1.79 src/sys/arch/evbarm/conf/GENERIC:1.80
--- src/sys/arch/evbarm/conf/GENERIC:1.79 Mon Jun 8 11:51:48 2020
+++ src/sys/arch/evbarm/conf/GENERIC Wed Jun 10 17:57:50 2020
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC,v 1.79 2020/06/08 11:51:48 jmcneill Exp $
+# $NetBSD: GENERIC,v 1.80 2020/06/10 17:57:50 jmcneill Exp $
#
# GENERIC ARM (aarch32) kernel
#
@@ -22,6 +22,7 @@ options SOC_EXYNOS5422
options SOC_IMX6DL
options SOC_IMX6Q
options SOC_IMX6QDL
+options SOC_IMX7D
options SOC_MESON8B
options SOC_OMAP3
options SOC_SUN4I_A10
@@ -106,7 +107,8 @@ cycvclkmgr* at fdt? pass 1 # Cyclone V
cycvrstmgr* at fdt? pass 0 # Cyclone V reset manager
exy5410clk* at fdt? pass 3 # Exynos5410 clock controller
exy5422clk* at fdt? pass 3 # Exynos5422 clock controller
-imxccm* at fdt? pass 1 # i.MX6 ccm
+imx6ccm* at fdt? pass 1 # i.MX6 CCM
+imx7dccm* at fdt? pass 2 # i.MX7D CCM
meson8bclkc* at fdt? pass 2 # Amlogic Meson8b clock controller
mesonresets* at fdt? pass 2 # Amlogic Meson misc. clock resets
omap3cm* at fdt? pass 1 # TI OMAP3 CM
@@ -178,6 +180,7 @@ armgic0 at gic?
bcmicu* at fdt? pass 1 # Broadcom BCM283x ICU
exyointr* at fdt? pass 1 # Samsung Exynos ICU
imxgpc* at fdt? pass 2 # i.MX General Power Controller INTC
+imx7gpc* at fdt? pass 2 # i.MX General Power Controller v2 INTC
omapintc* at fdt? pass 2 # TI OMAP INTC
tegralic* at fdt? pass 1 # NVIDIA Tegra LIC
sunxiintc* at fdt? pass 1 # Allwinner INTC
Added files:
Index: src/sys/arch/arm/imx/fdt/imx7_platform.c
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx7_platform.c:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx7_platform.c Wed Jun 10 17:57:50 2020
@@ -0,0 +1,195 @@
+/* $NetBSD: imx7_platform.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+/*-
+ * Copyright (c) 2019 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx7_platform.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $");
+
+#include "opt_console.h"
+#include "opt_fdt.h"
+#include "opt_multiprocessor.h"
+#include "opt_soc.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+#include <sys/termios.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <arm/fdt/arm_fdtvar.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <arm/arm32/machdep.h>
+
+#include <machine/bootconfig.h>
+#include <arm/cpufunc.h>
+
+#include <arm/cortex/gtmr_var.h>
+#include <arm/cortex/gic_reg.h>
+
+#include <arm/imx/imx7reg.h>
+#include <arm/imx/imx7_srcreg.h>
+#include <arm/imx/imx7_ccmreg.h>
+#include <arm/imx/imxuartreg.h>
+#include <arm/imx/imxwdogreg.h>
+
+#include <arm/imx/fdt/imx7_platform.h>
+
+#include <libfdt.h>
+
+extern struct bus_space armv7_generic_bs_tag;
+extern struct bus_space armv7_generic_a4x_bs_tag;
+extern struct arm32_bus_dma_tag arm_generic_dma_tag;
+
+static const struct pmap_devmap *
+imx7_platform_devmap(void)
+{
+ static const struct pmap_devmap devmap[] = {
+ DEVMAP_ENTRY(KERNEL_IO_IOREG_VBASE, IMX7_IOREG_PBASE, IMX7_IOREG_SIZE),
+ DEVMAP_ENTRY(KERNEL_IO_ARMCORE_VBASE, IMX7_ARMCORE_PBASE, IMX7_ARMCORE_SIZE),
+ DEVMAP_ENTRY_END
+ };
+
+ return devmap;
+}
+
+static void
+imx7_platform_init_attach_args(struct fdt_attach_args *faa)
+{
+ faa->faa_bst = &armv7_generic_bs_tag;
+ faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
+ faa->faa_dmat = &arm_generic_dma_tag;
+}
+
+void imx7_platform_early_putchar(char);
+
+void
+imx7_platform_early_putchar(char c)
+{
+#ifdef CONSADDR
+#define CONSADDR_VA ((CONSADDR - IMX7_IOREG_PBASE) + KERNEL_IO_IOREG_VBASE)
+
+ volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
+ (volatile uint32_t *)CONSADDR_VA :
+ (volatile uint32_t *)CONSADDR;
+
+ while ((le32toh(uartaddr[(IMX_USR2/4)]) & IMX_USR2_TXDC) == 0)
+ ;
+
+ uartaddr[(IMX_UTXD/4)] = htole32(c);
+#endif
+}
+
+static void
+imx7_platform_device_register(device_t self, void *aux)
+{
+ prop_dictionary_t prop = device_properties(self);
+
+ if (device_is_a(self, "atphy")) {
+ const char * compat[] = {
+ "fsl,imx7dl-sabresd",
+ "fsl,imx7q-sabresd",
+ "fsl,imx7qp-sabresd",
+ NULL
+ };
+ if (of_match_compatible(OF_finddevice("/"), compat))
+ prop_dictionary_set_uint32(prop, "clk_25m", 125000000);
+ }
+}
+
+static u_int
+imx7_platform_uart_freq(void)
+{
+ return IMX7_OSC_FREQ;
+}
+
+static int
+imx7_platform_mpstart(void)
+{
+#if defined(MULTIPROCESSOR)
+ bus_space_tag_t bst = &armv7_generic_bs_tag;
+ bus_space_handle_t bsh;
+
+ if (bus_space_map(bst, IMX7_IOREG_PBASE + AIPS1_SRC_BASE, AIPS1_SRC_SIZE, 0, &bsh) != 0)
+ panic("couldn't map aips1 src registers");
+ const paddr_t mpstart = KERN_VTOPHYS((vaddr_t)cpu_mpstart);
+
+ bus_space_write_4(bst, bsh, SRC_GPR3, mpstart);
+
+ uint32_t rcr1 = bus_space_read_4(bst, bsh, SRC_A7RCR1);
+ rcr1 |= SRC_A7RCR1_A7_CORE1_ENABLE;
+ bus_space_write_4(bst, bsh, SRC_A7RCR1, rcr1);
+
+ arm_dsb();
+ __asm __volatile("sev" ::: "memory");
+
+ /* Wait for AP to start */
+ for (u_int i = 0x1000000; i > 0; i--) {
+ if (cpu_hatched_p(1))
+ break;
+ }
+ if (!cpu_hatched_p(1))
+ printf("cpu1: WARNING: failed to start\n");
+
+ bus_space_unmap(bst, bsh, AIPS1_SRC_SIZE);
+#endif
+
+ return 0;
+}
+
+static void
+imx7_platform_reset(void)
+{
+ bus_space_tag_t bst = &armv7_generic_bs_tag;
+ bus_space_handle_t bsh;
+
+ if (bus_space_map(bst, IMX7_IOREG_PBASE + AIPS1_WDOG1_BASE, AIPS1_WDOG_SIZE, 0, &bsh))
+ panic("couldn't map wdog1 registers");
+
+ delay(1000); /* wait for flushing FIFO of serial console */
+
+ cpsid(I32_bit|F32_bit);
+
+ /* software reset signal on wdog */
+ bus_space_write_2(bst, bsh, IMX_WDOG_WCR, WCR_WDE);
+
+ for (;;)
+ __asm("wfi");
+}
+
+const struct arm_platform imx7_platform = {
+ .ap_devmap = imx7_platform_devmap,
+ .ap_bootstrap = arm_fdt_cpu_bootstrap,
+ .ap_init_attach_args = imx7_platform_init_attach_args,
+ .ap_device_register = imx7_platform_device_register,
+ .ap_reset = imx7_platform_reset,
+ .ap_delay = gtmr_delay,
+ .ap_uart_freq = imx7_platform_uart_freq,
+ .ap_mpstart = imx7_platform_mpstart,
+};
+
+ARM_PLATFORM(imx7d, "fsl,imx7d", &imx7_platform);
Index: src/sys/arch/arm/imx/fdt/imx7_platform.h
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx7_platform.h:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx7_platform.h Wed Jun 10 17:57:50 2020
@@ -0,0 +1,35 @@
+/* $NetBSD: imx7_platform.h,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+/*-
+ * Copyright (c) 2019 Genetec Corporation. All rights reserved.
+ * Written by Hashimoto Kenichi for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _ARM_IMX_FDT_IMX7_PLATFORM_H
+#define _ARM_IMX_FDT_IMX7_PLATFORM_H
+
+#include <arch/evbarm/fdt/platform.h>
+
+#define KERNEL_IO_IOREG_VBASE KERNEL_IO_VBASE
+#define KERNEL_IO_ARMCORE_VBASE (KERNEL_IO_IOREG_VBASE + IMX7_IOREG_SIZE)
+
+#endif /* _ARM_IMX_FDT_IMX7_PLATFORM_H */
Index: src/sys/arch/arm/imx/fdt/imx7d_ccm.c
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx7d_ccm.c:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx7d_ccm.c Wed Jun 10 17:57:50 2020
@@ -0,0 +1,325 @@
+/* $NetBSD: imx7d_ccm.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD: imx7d_ccm.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/imx/fdt/imx_ccm.h>
+#include <arm/imx/fdt/imx7d_ccm.h>
+
+static int imx7d_ccm_match(device_t, cfdata_t, void *);
+static void imx7d_ccm_attach(device_t, device_t, void *);
+
+static const char * const compatible[] = {
+ "fsl,imx7d-ccm",
+ NULL
+};
+
+static const char * const anatop_compatible[] = {
+ "fsl,imx7d-anatop",
+ NULL
+};
+
+static const char *pll_bypass_p[] = {
+ "osc", "dummy"
+};
+static const char *pll_sys_main_bypass_p[] = {
+ "pll_sys_main", "pll_sys_main_src"
+};
+static const char *pll_enet_main_bypass_p[] = {
+ "pll_enet_main", "pll_enet_main_src"
+};
+static const char *uart1357_p[] = {
+ "osc", "pll_sys_main_240m_clk", "pll_enet_40m_clk", "pll_enet_100m_clk", "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", "pll_usb_main_clk"
+};
+static const char *uart246_p[] = {
+ "osc", "pll_sys_main_240m_clk", "pll_enet_40m_clk", "pll_enet_100m_clk", "pll_sys_main_clk", "ext_clk_2", "ext_clk_4", "pll_usb_main_clk"
+};
+static const char *i2c_p[] = {
+ "osc", "pll_sys_main_120m_clk", "pll_enet_50m_clk", "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_post_div", "pll_usb_main_clk", "pll_sys_pfd2_135m_clk"
+};
+static const char *enet_axi_p[] = {
+ "osc", "pll_sys_pfd2_270m_clk", "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_post_div", "pll_sys_pfd4_clk"
+};
+static const char *enet_time_p[] = {
+ "osc", "pll_enet_100m_clk", "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3", "ext_clk_4", "pll_video_post_div"
+};
+static const char *enet_phy_ref_p[] = {
+ "osc", "pll_enet_25m_clk", "pll_enet_50m_clk", "pll_enet_125m_clk", "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_post_div", "pll_sys_pfd3_clk"
+};
+static const char *ahb_channel_p[] = {
+ "osc", "pll_sys_pfd2_270m_clk", "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_enet_250m_clk", "pll_usb_main_clk", "pll_audio_post_div", "pll_video_post_div"
+};
+static const char *nand_usdhc_p[] = {
+ "osc", "pll_sys_pfd2_270m_clk", "pll_dram_533m_clk", "pll_sys_main_240m_clk", "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", "pll_audio_post_div"
+};
+static const char *usdhc_p[] = {
+ "osc", "pll_sys_pfd0_392m_clk", "pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk", "pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk"
+};
+
+CFATTACH_DECL_NEW(imx7d_ccm, sizeof(struct imx_ccm_softc),
+ imx7d_ccm_match, imx7d_ccm_attach, NULL, NULL);
+
+enum {
+ REGIDX_CCM = 0,
+ REGIDX_ANATOP = 1,
+};
+
+#define ANATOP_MUX(_id, _name, _parents, _reg, _mask) \
+ IMX_MUX_INDEX(_id, REGIDX_ANATOP, _name, _parents, _reg, _mask)
+#define ANATOP_GATE(_id, _name, _parent, _reg, _mask) \
+ IMX_GATE_INDEX(_id, REGIDX_ANATOP, _name, _parent, _reg, _mask)
+#define ANATOP_PLL(_id, _name, _parent, _reg, _div_mask, _flags) \
+ IMX_PLL_INDEX(_id, REGIDX_ANATOP, _name, _parent, _reg, _div_mask, _flags)
+
+static struct imx_ccm_clk imx7d_ccm_clks[] = {
+
+ IMX_FIXED(CLK_DUMMY, "dummy", 0),
+ IMX_EXTCLK(CKIL, "ckil"),
+ IMX_EXTCLK(OSC_24M_CLK, "osc"),
+
+ /*
+ * CCM_ANALOG
+ */
+ ANATOP_MUX(PLL_SYS_MAIN_SRC, "pll_sys_main_src", pll_bypass_p, 0xb0, __BITS(15,14)),
+ ANATOP_MUX(PLL_ENET_MAIN_SRC, "pll_enet_main_src", pll_bypass_p, 0xe0, __BITS(15,14)),
+
+ ANATOP_PLL(PLL_SYS_MAIN, "pll_sys_main", "osc", 0xb0, __BIT(0), IMX_PLL_480M_528M),
+ ANATOP_PLL(PLL_ENET_MAIN, "pll_enet_main", "osc", 0xe0, 1000000000, IMX_PLL_ENET),
+
+ ANATOP_MUX(PLL_SYS_MAIN_BYPASS, "pll_sys_main_bypass", pll_sys_main_bypass_p, 0xb0, __BIT(16)),
+ ANATOP_MUX(PLL_ENET_MAIN_BYPASS, "pll_enet_main_bypass", pll_enet_main_bypass_p, 0xe0, __BIT(16)),
+
+ ANATOP_GATE(PLL_SYS_MAIN_CLK, "pll_sys_main_clk", "pll_sys_main_bypass", 0xb0, __BIT(13)),
+
+ IMX_FIXED_FACTOR(PLL_SYS_MAIN_240M, "pll_sys_main_240m", "pll_sys_main_clk", 1, 2),
+
+ ANATOP_GATE(PLL_SYS_MAIN_240M_CLK, "pll_sys_main_240m_clk", "pll_sys_main_240m", 0xb0, __BIT(5)),
+
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_CLK, "pll_enet_main_clk", "pll_enet_main_bypass", 1, 1),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_500M, "pll_enet_500m", "pll_enet_main_clk", 1, 2),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_250M, "pll_enet_250m", "pll_enet_main_clk", 1, 4),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_125M, "pll_enet_125m", "pll_enet_main_clk", 1, 8),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_100M, "pll_enet_100m", "pll_enet_main_clk", 1, 10),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_50M, "pll_enet_50m", "pll_enet_main_clk", 1, 20),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_40M, "pll_enet_40m", "pll_enet_main_clk", 1, 25),
+ IMX_FIXED_FACTOR(PLL_ENET_MAIN_25M, "pll_enet_25m", "pll_enet_main_clk", 1, 40),
+
+ ANATOP_GATE(PLL_ENET_MAIN_500M_CLK, "pll_enet_500m_clk", "pll_enet_500m", 0xe0, __BIT(12)),
+ ANATOP_GATE(PLL_ENET_MAIN_250M_CLK, "pll_enet_250m_clk", "pll_enet_250m", 0xe0, __BIT(11)),
+ ANATOP_GATE(PLL_ENET_MAIN_250M_CLK, "pll_enet_250m_clk", "pll_enet_250m", 0xe0, __BIT(11)),
+ ANATOP_GATE(PLL_ENET_MAIN_125M_CLK, "pll_enet_125m_clk", "pll_enet_125m", 0xe0, __BIT(10)),
+ ANATOP_GATE(PLL_ENET_MAIN_100M_CLK, "pll_enet_100m_clk", "pll_enet_100m", 0xe0, __BIT(9)),
+ ANATOP_GATE(PLL_ENET_MAIN_50M_CLK, "pll_enet_50m_clk", "pll_enet_50m", 0xe0, __BIT(8)),
+ ANATOP_GATE(PLL_ENET_MAIN_40M_CLK, "pll_enet_40m_clk", "pll_enet_40m", 0xe0, __BIT(7)),
+ ANATOP_GATE(PLL_ENET_MAIN_25M_CLK, "pll_enet_25m_clk", "pll_enet_25m", 0xe0, __BIT(6)),
+
+ IMX_FIXED_FACTOR(USB1_MAIN_480M_CLK, "pll_usb1_main_clk", "osc", 20, 1),
+ IMX_FIXED_FACTOR(USB_MAIN_480M_CLK, "pll_usb_main_clk", "osc", 20, 1),
+
+ /*
+ * CCM (regidx=0)
+ */
+
+ IMX_MUX(UART1_ROOT_SRC, "uart1_src", uart1357_p, 0xaf80, __BITS(26,24)),
+ IMX_MUX(UART2_ROOT_SRC, "uart2_src", uart246_p, 0xb000, __BITS(26,24)),
+ IMX_MUX(UART3_ROOT_SRC, "uart3_src", uart1357_p, 0xb080, __BITS(26,24)),
+ IMX_MUX(UART4_ROOT_SRC, "uart4_src", uart246_p, 0xb100, __BITS(26,24)),
+ IMX_MUX(UART5_ROOT_SRC, "uart5_src", uart1357_p, 0xb180, __BITS(26,24)),
+ IMX_MUX(UART6_ROOT_SRC, "uart6_src", uart246_p, 0xb200, __BITS(26,24)),
+ IMX_MUX(UART7_ROOT_SRC, "uart7_src", uart1357_p, 0xb280, __BITS(26,24)),
+
+ IMX_GATE(UART1_ROOT_CG, "uart1_cg", "uart1_src", 0xaf80, __BIT(18)),
+ IMX_GATE(UART2_ROOT_CG, "uart2_cg", "uart2_src", 0xb000, __BIT(18)),
+ IMX_GATE(UART3_ROOT_CG, "uart3_cg", "uart3_src", 0xb080, __BIT(18)),
+ IMX_GATE(UART4_ROOT_CG, "uart4_cg", "uart4_src", 0xb100, __BIT(18)),
+ IMX_GATE(UART5_ROOT_CG, "uart5_cg", "uart5_src", 0xb180, __BIT(18)),
+ IMX_GATE(UART6_ROOT_CG, "uart6_cg", "uart6_src", 0xb200, __BIT(18)),
+ IMX_GATE(UART7_ROOT_CG, "uart7_cg", "uart7_src", 0xb280, __BIT(18)),
+
+ IMX_DIV(UART1_ROOT_PRE_DIV, "uart1_pre_div", "uart1_cg", 0xaf80, __BITS(18,16), 0),
+ IMX_DIV(UART2_ROOT_PRE_DIV, "uart2_pre_div", "uart2_cg", 0xb000, __BITS(18,16), 0),
+ IMX_DIV(UART3_ROOT_PRE_DIV, "uart3_pre_div", "uart3_cg", 0xb080, __BITS(18,16), 0),
+ IMX_DIV(UART4_ROOT_PRE_DIV, "uart4_pre_div", "uart4_cg", 0xb100, __BITS(18,16), 0),
+ IMX_DIV(UART5_ROOT_PRE_DIV, "uart5_pre_div", "uart5_cg", 0xb100, __BITS(18,16), 0),
+ IMX_DIV(UART6_ROOT_PRE_DIV, "uart6_pre_div", "uart6_cg", 0xb200, __BITS(18,16), 0),
+ IMX_DIV(UART7_ROOT_PRE_DIV, "uart7_pre_div", "uart7_cg", 0xb280, __BITS(18,16), 0),
+
+ IMX_DIV(UART1_ROOT_DIV, "uart1_post_div", "uart1_pre_div", 0xaf80, __BITS(5,0), 0),
+ IMX_DIV(UART2_ROOT_DIV, "uart2_post_div", "uart2_pre_div", 0xb000, __BITS(5,0), 0),
+ IMX_DIV(UART3_ROOT_DIV, "uart3_post_div", "uart3_pre_div", 0xb080, __BITS(5,0), 0),
+ IMX_DIV(UART4_ROOT_DIV, "uart4_post_div", "uart4_pre_div", 0xb100, __BITS(5,0), 0),
+ IMX_DIV(UART5_ROOT_DIV, "uart5_post_div", "uart5_pre_div", 0xb100, __BITS(5,0), 0),
+ IMX_DIV(UART6_ROOT_DIV, "uart6_post_div", "uart6_pre_div", 0xb200, __BITS(5,0), 0),
+ IMX_DIV(UART7_ROOT_DIV, "uart7_post_div", "uart7_pre_div", 0xb280, __BITS(5,0), 0),
+
+ IMX_GATE(UART1_ROOT_CLK, "uart1_root_clk", "uart1_post_div", 0x4940, __BIT(0)),
+ IMX_GATE(UART2_ROOT_CLK, "uart2_root_clk", "uart2_post_div", 0x4950, __BIT(0)),
+ IMX_GATE(UART3_ROOT_CLK, "uart3_root_clk", "uart3_post_div", 0x4960, __BIT(0)),
+ IMX_GATE(UART4_ROOT_CLK, "uart4_root_clk", "uart4_post_div", 0x4970, __BIT(0)),
+ IMX_GATE(UART5_ROOT_CLK, "uart5_root_clk", "uart5_post_div", 0x4980, __BIT(0)),
+ IMX_GATE(UART6_ROOT_CLK, "uart6_root_clk", "uart6_post_div", 0x4990, __BIT(0)),
+ IMX_GATE(UART7_ROOT_CLK, "uart7_root_clk", "uart7_post_div", 0x49a0, __BIT(0)),
+
+ IMX_MUX(I2C1_ROOT_SRC, "i2c1_src", i2c_p, 0xad80, __BITS(26,24)),
+ IMX_MUX(I2C2_ROOT_SRC, "i2c2_src", i2c_p, 0xae00, __BITS(26,24)),
+ IMX_MUX(I2C3_ROOT_SRC, "i2c3_src", i2c_p, 0xae80, __BITS(26,24)),
+ IMX_MUX(I2C4_ROOT_SRC, "i2c4_src", i2c_p, 0xaf00, __BITS(26,24)),
+
+ IMX_GATE(I2C1_ROOT_CG, "i2c1_cg", "i2c1_src", 0xad80, __BIT(0)),
+ IMX_GATE(I2C2_ROOT_CG, "i2c2_cg", "i2c2_src", 0xae00, __BIT(0)),
+ IMX_GATE(I2C3_ROOT_CG, "i2c3_cg", "i2c3_src", 0xae80, __BIT(0)),
+ IMX_GATE(I2C4_ROOT_CG, "i2c4_cg", "i2c4_src", 0xaf00, __BIT(0)),
+
+ IMX_DIV(I2C1_ROOT_PRE_DIV, "i2c1_pre_div", "i2c1_cg", 0xad80, __BITS(18,16), 0),
+ IMX_DIV(I2C2_ROOT_PRE_DIV, "i2c2_pre_div", "i2c2_cg", 0xae00, __BITS(18,16), 0),
+ IMX_DIV(I2C3_ROOT_PRE_DIV, "i2c3_pre_div", "i2c3_cg", 0xae80, __BITS(18,16), 0),
+ IMX_DIV(I2C4_ROOT_PRE_DIV, "i2c4_pre_div", "i2c4_cg", 0xaf00, __BITS(18,16), 0),
+
+ IMX_DIV(I2C1_ROOT_DIV, "i2c1_post_div", "i2c1_pre_div", 0xad80, __BITS(5,0), 0),
+ IMX_DIV(I2C2_ROOT_DIV, "i2c2_post_div", "i2c2_pre_div", 0xae00, __BITS(5,0), 0),
+ IMX_DIV(I2C3_ROOT_DIV, "i2c3_post_div", "i2c3_pre_div", 0xae80, __BITS(5,0), 0),
+ IMX_DIV(I2C4_ROOT_DIV, "i2c4_post_div", "i2c4_pre_div", 0xaf00, __BITS(5,0), 0),
+
+ IMX_GATE(I2C1_ROOT_CLK, "i2c1_root_clk", "i2c1_post_div", 0x4880, __BIT(0)),
+ IMX_GATE(I2C2_ROOT_CLK, "i2c2_root_clk", "i2c2_post_div", 0x4890, __BIT(0)),
+ IMX_GATE(I2C3_ROOT_CLK, "i2c3_root_clk", "i2c3_post_div", 0x48a0, __BIT(0)),
+ IMX_GATE(I2C4_ROOT_CLK, "i2c4_root_clk", "i2c4_post_div", 0x48b0, __BIT(0)),
+
+ IMX_MUX(ENET_AXI_ROOT_SRC, "enet_axi_src", enet_axi_p, 0x8900, __BITS(26,24)),
+ IMX_GATE(ENET_AXI_ROOT_CG, "enet_axi_cg", "enet_axi_src", 0x8900, __BIT(28)),
+ IMX_DIV(ENET_AXI_ROOT_PRE_DIV, "enet_axi_pre_div", "enet_axi_cg", 0x8900, __BITS(18,16), 0),
+ IMX_DIV(ENET_AXI_ROOT_DIV, "enet_axi_post_div", "enet_axi_pre_div", 0x8900, __BITS(5,0), 0),
+
+ IMX_MUX(ENET1_TIME_ROOT_SRC, "enet1_time_src", enet_time_p, 0xa780, __BITS(26,24)),
+ IMX_MUX(ENET2_TIME_ROOT_SRC, "enet2_time_src", enet_time_p, 0xa880, __BITS(26,24)),
+ IMX_GATE(ENET1_TIME_ROOT_CG, "enet1_time_cg", "enet1_time_src", 0xa780, __BIT(28)),
+ IMX_GATE(ENET2_TIME_ROOT_CG, "enet2_time_cg", "enet2_time_src", 0xa880, __BIT(28)),
+ IMX_DIV(ENET1_TIME_ROOT_PRE_DIV, "enet1_time_pre_div", "enet1_time_cg", 0xa780, __BITS(18,16), 0),
+ IMX_DIV(ENET2_TIME_ROOT_PRE_DIV, "enet2_time_pre_div", "enet2_time_cg", 0xa880, __BITS(18,16), 0),
+ IMX_DIV(ENET1_TIME_ROOT_DIV, "enet1_time_post_div", "enet1_time_pre_div", 0xa780, __BITS(5,0), 0),
+ IMX_DIV(ENET2_TIME_ROOT_DIV, "enet2_time_post_div", "enet2_time_pre_div", 0xa880, __BITS(5,0), 0),
+ IMX_GATE(ENET1_IPG_ROOT_CLK, "enet1_ipg_root_clk", "enet_axi_post_div", 0x4700, __BIT(0)),
+ IMX_GATE(ENET2_IPG_ROOT_CLK, "enet2_ipg_root_clk", "enet_axi_post_div", 0x4710, __BIT(0)),
+ IMX_GATE(ENET1_TIME_ROOT_CLK, "enet1_time_root_clk", "enet1_time_post_div", 0x4700, __BIT(0)),
+ IMX_GATE(ENET2_TIME_ROOT_CLK, "enet2_time_root_clk", "enet2_time_post_div", 0x4710, __BIT(0)),
+ IMX_GATE(ENET_AXI_ROOT_CLK, "enet_axi_root_clk", "enet_axi_post_div", 0x4060, __BIT(0)),
+
+ IMX_MUX(ENET_PHY_REF_ROOT_SRC, "enet_phy_ref_src", enet_phy_ref_p, 0xa900, __BITS(26,24)),
+ IMX_GATE(ENET_PHY_REF_ROOT_CG, "enet_phy_ref_cg", "enet_phy_ref_src", 0xa900, __BIT(28)),
+ IMX_DIV(ENET_PHY_REF_ROOT_PRE_DIV, "enet_phy_ref_pre_div", "enet_phy_ref_cg", 0xa900, __BITS(18,16), 0),
+ IMX_DIV(ENET_PHY_REF_ROOT_CLK, "enet_phy_ref_root_clk", "enet_phy_ref_pre_div", 0xa900, __BITS(5,0), 0),
+
+ IMX_MUX(AHB_CHANNEL_ROOT_SRC, "ahb_src", ahb_channel_p, 0x9000, __BITS(26,24)),
+ IMX_GATE(AHB_CHANNEL_ROOT_CG, "ahb_cg", "ahb_src", 0x9000, __BIT(28)),
+ IMX_DIV(AHB_CHANNEL_ROOT_PRE_DIV, "ahb_pre_div", "ahb_cg", 0x9000, __BITS(18,16), 0),
+ IMX_DIV(AHB_CHANNEL_ROOT_DIV, "ahb_root_clk", "ahb_pre_div", 0x9000, __BITS(5,0), 0),
+ IMX_DIV(IPG_ROOT_CLK, "ipg_root_clk", "ahb_root_clk", 0x9080, __BITS(1,0), IMX_DIV_SET_RATE_PARENT),
+
+ IMX_MUX(NAND_USDHC_BUS_ROOT_SRC, "nand_usdhc_src", nand_usdhc_p, 0x8980, __BITS(26,24)),
+ IMX_GATE(NAND_USDHC_BUS_ROOT_CG, "nand_usdhc_cg", "nand_usdhc_src", 0x8980, __BIT(28)),
+ IMX_DIV(NAND_USDHC_BUS_ROOT_PRE_DIV, "nand_usdhc_pre_div", "nand_usdhc_cg", 0x8980, __BITS(18,16), 0),
+ IMX_DIV(NAND_USDHC_BUS_ROOT_CLK, "nand_usdhc_root_clk", "nand_usdhc_pre_div", 0x8980, __BITS(5,0), 0),
+
+ IMX_MUX(USDHC1_ROOT_SRC, "usdhc1_src", usdhc_p, 0xab00, __BITS(26,24)),
+ IMX_MUX(USDHC2_ROOT_SRC, "usdhc2_src", usdhc_p, 0xab80, __BITS(26,24)),
+ IMX_MUX(USDHC3_ROOT_SRC, "usdhc3_src", usdhc_p, 0xac00, __BITS(26,24)),
+ IMX_GATE(USDHC1_ROOT_CG, "usdhc1_cg", "usdhc1_src", 0xab00, __BIT(28)),
+ IMX_GATE(USDHC2_ROOT_CG, "usdhc2_cg", "usdhc2_src", 0xab80, __BIT(28)),
+ IMX_GATE(USDHC3_ROOT_CG, "usdhc3_cg", "usdhc3_src", 0xac00, __BIT(28)),
+ IMX_DIV(USDHC1_ROOT_PRE_DIV, "usdhc1_pre_div", "usdhc1_cg", 0xab00, __BITS(18,16), 0),
+ IMX_DIV(USDHC1_ROOT_PRE_DIV, "usdhc2_pre_div", "usdhc2_cg", 0xab80, __BITS(18,16), 0),
+ IMX_DIV(USDHC1_ROOT_PRE_DIV, "usdhc3_pre_div", "usdhc3_cg", 0xac00, __BITS(18,16), 0),
+ IMX_DIV(USDHC1_ROOT_DIV, "usdhc1_post_div", "usdhc1_pre_div", 0xab00, __BITS(5,0), 0),
+ IMX_DIV(USDHC2_ROOT_DIV, "usdhc2_post_div", "usdhc2_pre_div", 0xab80, __BITS(5,0), 0),
+ IMX_DIV(USDHC3_ROOT_DIV, "usdhc3_post_div", "usdhc3_pre_div", 0xac00, __BITS(5,0), 0),
+ IMX_GATE(USDHC1_ROOT_CLK, "usdhc1_root_clk", "usdhc1_post_div", 0x46c0, __BIT(0)),
+ IMX_GATE(USDHC2_ROOT_CLK, "usdhc2_root_clk", "usdhc2_post_div", 0x46d0, __BIT(0)),
+ IMX_GATE(USDHC3_ROOT_CLK, "usdhc3_root_clk", "usdhc3_post_div", 0x46e0, __BIT(0)),
+};
+
+static int
+imx7d_ccm_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+imx7d_ccm_attach(device_t parent, device_t self, void *aux)
+{
+ struct imx_ccm_softc * const sc = device_private(self);
+ struct fdt_attach_args * const faa = aux;
+ const int phandle = faa->faa_phandle;
+ bus_addr_t anatop_addr;
+ bus_size_t anatop_size;
+ int anatop = -1, child;
+
+ sc->sc_dev = self;
+ sc->sc_phandle = phandle;
+ sc->sc_bst = faa->faa_bst;
+
+ sc->sc_clks = imx7d_ccm_clks;
+ sc->sc_nclks = __arraycount(imx7d_ccm_clks);
+
+ for (child = OF_child(OF_parent(phandle)); child; child = OF_peer(child)) {
+ if (of_match_compatible(child, anatop_compatible) > 0) {
+ anatop = child;
+ break;
+ }
+ }
+ if (anatop == -1) {
+ aprint_error(": couldn't find anatop node\n");
+ return;
+ }
+ if (fdtbus_get_reg(anatop, 0, &anatop_addr, &anatop_size) != 0) {
+ aprint_error(": couldn't get anatop registers\n");
+ return;
+ }
+ if (bus_space_map(sc->sc_bst, anatop_addr, anatop_size, 0, &sc->sc_bsh[REGIDX_ANATOP]) != 0) {
+ aprint_error(": couldn't map anatop registers\n");
+ return;
+ }
+
+ if (imx_ccm_attach(sc) != 0)
+ return;
+
+ aprint_naive("\n");
+ aprint_normal(": Clock Control Module\n");
+
+ imx_ccm_print(sc);
+}
Index: src/sys/arch/arm/imx/fdt/imx7d_ccm.h
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx7d_ccm.h:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx7d_ccm.h Wed Jun 10 17:57:50 2020
@@ -0,0 +1,482 @@
+/* $NetBSD: imx7d_ccm.h,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _IMX7D_CCM_H
+#define _IMX7D_CCM_H
+
+/*
+ * Clocks
+ */
+
+#define OSC_24M_CLK 0
+#define PLL_ARM_MAIN 1
+#define PLL_ARM_MAIN_CLK 2
+#define PLL_ARM_MAIN_SRC 3
+#define PLL_ARM_MAIN_BYPASS 4
+#define PLL_SYS_MAIN 5
+#define PLL_SYS_MAIN_CLK 6
+#define PLL_SYS_MAIN_SRC 7
+#define PLL_SYS_MAIN_BYPASS 8
+#define PLL_SYS_MAIN_480M 9
+#define PLL_SYS_MAIN_240M 10
+#define PLL_SYS_MAIN_120M 11
+#define PLL_SYS_MAIN_480M_CLK 12
+#define PLL_SYS_MAIN_240M_CLK 13
+#define PLL_SYS_MAIN_120M_CLK 14
+#define PLL_SYS_PFD0_392M_CLK 15
+#define PLL_SYS_PFD0_196M 16
+#define PLL_SYS_PFD0_196M_CLK 17
+#define PLL_SYS_PFD1_332M_CLK 18
+#define PLL_SYS_PFD1_166M 19
+#define PLL_SYS_PFD1_166M_CLK 20
+#define PLL_SYS_PFD2_270M_CLK 21
+#define PLL_SYS_PFD2_135M 22
+#define PLL_SYS_PFD2_135M_CLK 23
+#define PLL_SYS_PFD3_CLK 24
+#define PLL_SYS_PFD4_CLK 25
+#define PLL_SYS_PFD5_CLK 26
+#define PLL_SYS_PFD6_CLK 27
+#define PLL_SYS_PFD7_CLK 28
+#define PLL_ENET_MAIN 29
+#define PLL_ENET_MAIN_CLK 30
+#define PLL_ENET_MAIN_SRC 31
+#define PLL_ENET_MAIN_BYPASS 32
+#define PLL_ENET_MAIN_500M 33
+#define PLL_ENET_MAIN_250M 34
+#define PLL_ENET_MAIN_125M 35
+#define PLL_ENET_MAIN_100M 36
+#define PLL_ENET_MAIN_50M 37
+#define PLL_ENET_MAIN_40M 38
+#define PLL_ENET_MAIN_25M 39
+#define PLL_ENET_MAIN_500M_CLK 40
+#define PLL_ENET_MAIN_250M_CLK 41
+#define PLL_ENET_MAIN_125M_CLK 42
+#define PLL_ENET_MAIN_100M_CLK 43
+#define PLL_ENET_MAIN_50M_CLK 44
+#define PLL_ENET_MAIN_40M_CLK 45
+#define PLL_ENET_MAIN_25M_CLK 46
+#define PLL_DRAM_MAIN 47
+#define PLL_DRAM_MAIN_CLK 48
+#define PLL_DRAM_MAIN_SRC 49
+#define PLL_DRAM_MAIN_BYPASS 50
+#define PLL_DRAM_MAIN_533M 51
+#define PLL_DRAM_MAIN_533M_CLK 52
+#define PLL_AUDIO_MAIN 53
+#define PLL_AUDIO_MAIN_CLK 54
+#define PLL_AUDIO_MAIN_SRC 55
+#define PLL_AUDIO_MAIN_BYPASS 56
+#define PLL_VIDEO_MAIN_CLK 57
+#define PLL_VIDEO_MAIN 58
+#define PLL_VIDEO_MAIN_SRC 59
+#define PLL_VIDEO_MAIN_BYPASS 60
+#define USB_MAIN_480M_CLK 61
+#define ARM_A7_ROOT_CLK 62
+#define ARM_A7_ROOT_SRC 63
+#define ARM_A7_ROOT_CG 64
+#define ARM_A7_ROOT_DIV 65
+#define ARM_M4_ROOT_CLK 66
+#define ARM_M4_ROOT_SRC 67
+#define ARM_M4_ROOT_CG 68
+#define ARM_M4_ROOT_DIV 69
+#define ARM_M0_ROOT_CLK 70
+#define ARM_M0_ROOT_SRC 71
+#define ARM_M0_ROOT_CG 72
+#define ARM_M0_ROOT_DIV 73
+#define MAIN_AXI_ROOT_CLK 74
+#define MAIN_AXI_ROOT_SRC 75
+#define MAIN_AXI_ROOT_CG 76
+#define MAIN_AXI_ROOT_DIV 77
+#define DISP_AXI_ROOT_CLK 78
+#define DISP_AXI_ROOT_SRC 79
+#define DISP_AXI_ROOT_CG 80
+#define DISP_AXI_ROOT_DIV 81
+#define ENET_AXI_ROOT_CLK 82
+#define ENET_AXI_ROOT_SRC 83
+#define ENET_AXI_ROOT_CG 84
+#define ENET_AXI_ROOT_DIV 85
+#define NAND_USDHC_BUS_ROOT_CLK 86
+#define NAND_USDHC_BUS_ROOT_SRC 87
+#define NAND_USDHC_BUS_ROOT_CG 88
+#define NAND_USDHC_BUS_ROOT_DIV 89
+#define AHB_CHANNEL_ROOT_CLK 90
+#define AHB_CHANNEL_ROOT_SRC 91
+#define AHB_CHANNEL_ROOT_CG 92
+#define AHB_CHANNEL_ROOT_DIV 93
+#define DRAM_PHYM_ROOT_CLK 94
+#define DRAM_PHYM_ROOT_SRC 95
+#define DRAM_PHYM_ROOT_CG 96
+#define DRAM_PHYM_ROOT_DIV 97
+#define DRAM_ROOT_CLK 98
+#define DRAM_ROOT_SRC 99
+#define DRAM_ROOT_CG 100
+#define DRAM_ROOT_DIV 101
+#define DRAM_PHYM_ALT_ROOT_CLK 102
+#define DRAM_PHYM_ALT_ROOT_SRC 103
+#define DRAM_PHYM_ALT_ROOT_CG 104
+#define DRAM_PHYM_ALT_ROOT_DIV 105
+#define DRAM_ALT_ROOT_CLK 106
+#define DRAM_ALT_ROOT_SRC 107
+#define DRAM_ALT_ROOT_CG 108
+#define DRAM_ALT_ROOT_DIV 109
+#define USB_HSIC_ROOT_CLK 110
+#define USB_HSIC_ROOT_SRC 111
+#define USB_HSIC_ROOT_CG 112
+#define USB_HSIC_ROOT_DIV 113
+#define PCIE_CTRL_ROOT_CLK 114
+#define PCIE_CTRL_ROOT_SRC 115
+#define PCIE_CTRL_ROOT_CG 116
+#define PCIE_CTRL_ROOT_DIV 117
+#define PCIE_PHY_ROOT_CLK 118
+#define PCIE_PHY_ROOT_SRC 119
+#define PCIE_PHY_ROOT_CG 120
+#define PCIE_PHY_ROOT_DIV 121
+#define EPDC_PIXEL_ROOT_CLK 122
+#define EPDC_PIXEL_ROOT_SRC 123
+#define EPDC_PIXEL_ROOT_CG 124
+#define EPDC_PIXEL_ROOT_DIV 125
+#define LCDIF_PIXEL_ROOT_CLK 126
+#define LCDIF_PIXEL_ROOT_SRC 127
+#define LCDIF_PIXEL_ROOT_CG 128
+#define LCDIF_PIXEL_ROOT_DIV 129
+#define MIPI_DSI_ROOT_CLK 130
+#define MIPI_DSI_ROOT_SRC 131
+#define MIPI_DSI_ROOT_CG 132
+#define MIPI_DSI_ROOT_DIV 133
+#define MIPI_CSI_ROOT_CLK 134
+#define MIPI_CSI_ROOT_SRC 135
+#define MIPI_CSI_ROOT_CG 136
+#define MIPI_CSI_ROOT_DIV 137
+#define MIPI_DPHY_ROOT_CLK 138
+#define MIPI_DPHY_ROOT_SRC 139
+#define MIPI_DPHY_ROOT_CG 140
+#define MIPI_DPHY_ROOT_DIV 141
+#define SAI1_ROOT_CLK 142
+#define SAI1_ROOT_SRC 143
+#define SAI1_ROOT_CG 144
+#define SAI1_ROOT_DIV 145
+#define SAI2_ROOT_CLK 146
+#define SAI2_ROOT_SRC 147
+#define SAI2_ROOT_CG 148
+#define SAI2_ROOT_DIV 149
+#define SAI3_ROOT_CLK 150
+#define SAI3_ROOT_SRC 151
+#define SAI3_ROOT_CG 152
+#define SAI3_ROOT_DIV 153
+#define SPDIF_ROOT_CLK 154
+#define SPDIF_ROOT_SRC 155
+#define SPDIF_ROOT_CG 156
+#define SPDIF_ROOT_DIV 157
+#define ENET1_IPG_ROOT_CLK 158
+#define ENET1_REF_ROOT_SRC 159
+#define ENET1_REF_ROOT_CG 160
+#define ENET1_REF_ROOT_DIV 161
+#define ENET1_TIME_ROOT_CLK 162
+#define ENET1_TIME_ROOT_SRC 163
+#define ENET1_TIME_ROOT_CG 164
+#define ENET1_TIME_ROOT_DIV 165
+#define ENET2_IPG_ROOT_CLK 166
+#define ENET2_REF_ROOT_SRC 167
+#define ENET2_REF_ROOT_CG 168
+#define ENET2_REF_ROOT_DIV 169
+#define ENET2_TIME_ROOT_CLK 170
+#define ENET2_TIME_ROOT_SRC 171
+#define ENET2_TIME_ROOT_CG 172
+#define ENET2_TIME_ROOT_DIV 173
+#define ENET_PHY_REF_ROOT_CLK 174
+#define ENET_PHY_REF_ROOT_SRC 175
+#define ENET_PHY_REF_ROOT_CG 176
+#define ENET_PHY_REF_ROOT_DIV 177
+#define EIM_ROOT_CLK 178
+#define EIM_ROOT_SRC 179
+#define EIM_ROOT_CG 180
+#define EIM_ROOT_DIV 181
+#define NAND_ROOT_CLK 182
+#define NAND_ROOT_SRC 183
+#define NAND_ROOT_CG 184
+#define NAND_ROOT_DIV 185
+#define QSPI_ROOT_CLK 186
+#define QSPI_ROOT_SRC 187
+#define QSPI_ROOT_CG 188
+#define QSPI_ROOT_DIV 189
+#define USDHC1_ROOT_CLK 190
+#define USDHC1_ROOT_SRC 191
+#define USDHC1_ROOT_CG 192
+#define USDHC1_ROOT_DIV 193
+#define USDHC2_ROOT_CLK 194
+#define USDHC2_ROOT_SRC 195
+#define USDHC2_ROOT_CG 196
+#define USDHC2_ROOT_DIV 197
+#define USDHC3_ROOT_CLK 198
+#define USDHC3_ROOT_SRC 199
+#define USDHC3_ROOT_CG 200
+#define USDHC3_ROOT_DIV 201
+#define CAN1_ROOT_CLK 202
+#define CAN1_ROOT_SRC 203
+#define CAN1_ROOT_CG 204
+#define CAN1_ROOT_DIV 205
+#define CAN2_ROOT_CLK 206
+#define CAN2_ROOT_SRC 207
+#define CAN2_ROOT_CG 208
+#define CAN2_ROOT_DIV 209
+#define I2C1_ROOT_CLK 210
+#define I2C1_ROOT_SRC 211
+#define I2C1_ROOT_CG 212
+#define I2C1_ROOT_DIV 213
+#define I2C2_ROOT_CLK 214
+#define I2C2_ROOT_SRC 215
+#define I2C2_ROOT_CG 216
+#define I2C2_ROOT_DIV 217
+#define I2C3_ROOT_CLK 218
+#define I2C3_ROOT_SRC 219
+#define I2C3_ROOT_CG 220
+#define I2C3_ROOT_DIV 221
+#define I2C4_ROOT_CLK 222
+#define I2C4_ROOT_SRC 223
+#define I2C4_ROOT_CG 224
+#define I2C4_ROOT_DIV 225
+#define UART1_ROOT_CLK 226
+#define UART1_ROOT_SRC 227
+#define UART1_ROOT_CG 228
+#define UART1_ROOT_DIV 229
+#define UART2_ROOT_CLK 230
+#define UART2_ROOT_SRC 231
+#define UART2_ROOT_CG 232
+#define UART2_ROOT_DIV 233
+#define UART3_ROOT_CLK 234
+#define UART3_ROOT_SRC 235
+#define UART3_ROOT_CG 236
+#define UART3_ROOT_DIV 237
+#define UART4_ROOT_CLK 238
+#define UART4_ROOT_SRC 239
+#define UART4_ROOT_CG 240
+#define UART4_ROOT_DIV 241
+#define UART5_ROOT_CLK 242
+#define UART5_ROOT_SRC 243
+#define UART5_ROOT_CG 244
+#define UART5_ROOT_DIV 245
+#define UART6_ROOT_CLK 246
+#define UART6_ROOT_SRC 247
+#define UART6_ROOT_CG 248
+#define UART6_ROOT_DIV 249
+#define UART7_ROOT_CLK 250
+#define UART7_ROOT_SRC 251
+#define UART7_ROOT_CG 252
+#define UART7_ROOT_DIV 253
+#define ECSPI1_ROOT_CLK 254
+#define ECSPI1_ROOT_SRC 255
+#define ECSPI1_ROOT_CG 256
+#define ECSPI1_ROOT_DIV 257
+#define ECSPI2_ROOT_CLK 258
+#define ECSPI2_ROOT_SRC 259
+#define ECSPI2_ROOT_CG 260
+#define ECSPI2_ROOT_DIV 261
+#define ECSPI3_ROOT_CLK 262
+#define ECSPI3_ROOT_SRC 263
+#define ECSPI3_ROOT_CG 264
+#define ECSPI3_ROOT_DIV 265
+#define ECSPI4_ROOT_CLK 266
+#define ECSPI4_ROOT_SRC 267
+#define ECSPI4_ROOT_CG 268
+#define ECSPI4_ROOT_DIV 269
+#define PWM1_ROOT_CLK 270
+#define PWM1_ROOT_SRC 271
+#define PWM1_ROOT_CG 272
+#define PWM1_ROOT_DIV 273
+#define PWM2_ROOT_CLK 274
+#define PWM2_ROOT_SRC 275
+#define PWM2_ROOT_CG 276
+#define PWM2_ROOT_DIV 277
+#define PWM3_ROOT_CLK 278
+#define PWM3_ROOT_SRC 279
+#define PWM3_ROOT_CG 280
+#define PWM3_ROOT_DIV 281
+#define PWM4_ROOT_CLK 282
+#define PWM4_ROOT_SRC 283
+#define PWM4_ROOT_CG 284
+#define PWM4_ROOT_DIV 285
+#define FLEXTIMER1_ROOT_CLK 286
+#define FLEXTIMER1_ROOT_SRC 287
+#define FLEXTIMER1_ROOT_CG 288
+#define FLEXTIMER1_ROOT_DIV 289
+#define FLEXTIMER2_ROOT_CLK 290
+#define FLEXTIMER2_ROOT_SRC 291
+#define FLEXTIMER2_ROOT_CG 292
+#define FLEXTIMER2_ROOT_DIV 293
+#define SIM1_ROOT_CLK 294
+#define SIM1_ROOT_SRC 295
+#define SIM1_ROOT_CG 296
+#define SIM1_ROOT_DIV 297
+#define SIM2_ROOT_CLK 298
+#define SIM2_ROOT_SRC 299
+#define SIM2_ROOT_CG 300
+#define SIM2_ROOT_DIV 301
+#define GPT1_ROOT_CLK 302
+#define GPT1_ROOT_SRC 303
+#define GPT1_ROOT_CG 304
+#define GPT1_ROOT_DIV 305
+#define GPT2_ROOT_CLK 306
+#define GPT2_ROOT_SRC 307
+#define GPT2_ROOT_CG 308
+#define GPT2_ROOT_DIV 309
+#define GPT3_ROOT_CLK 310
+#define GPT3_ROOT_SRC 311
+#define GPT3_ROOT_CG 312
+#define GPT3_ROOT_DIV 313
+#define GPT4_ROOT_CLK 314
+#define GPT4_ROOT_SRC 315
+#define GPT4_ROOT_CG 316
+#define GPT4_ROOT_DIV 317
+#define TRACE_ROOT_CLK 318
+#define TRACE_ROOT_SRC 319
+#define TRACE_ROOT_CG 320
+#define TRACE_ROOT_DIV 321
+#define WDOG1_ROOT_CLK 322
+#define WDOG_ROOT_SRC 323
+#define WDOG_ROOT_CG 324
+#define WDOG_ROOT_DIV 325
+#define CSI_MCLK_ROOT_CLK 326
+#define CSI_MCLK_ROOT_SRC 327
+#define CSI_MCLK_ROOT_CG 328
+#define CSI_MCLK_ROOT_DIV 329
+#define AUDIO_MCLK_ROOT_CLK 330
+#define AUDIO_MCLK_ROOT_SRC 331
+#define AUDIO_MCLK_ROOT_CG 332
+#define AUDIO_MCLK_ROOT_DIV 333
+#define WRCLK_ROOT_CLK 334
+#define WRCLK_ROOT_SRC 335
+#define WRCLK_ROOT_CG 336
+#define WRCLK_ROOT_DIV 337
+#define CLKO1_ROOT_SRC 338
+#define CLKO1_ROOT_CG 339
+#define CLKO1_ROOT_DIV 340
+#define CLKO2_ROOT_SRC 341
+#define CLKO2_ROOT_CG 342
+#define CLKO2_ROOT_DIV 343
+#define MAIN_AXI_ROOT_PRE_DIV 344
+#define DISP_AXI_ROOT_PRE_DIV 345
+#define ENET_AXI_ROOT_PRE_DIV 346
+#define NAND_USDHC_BUS_ROOT_PRE_DIV 347
+#define AHB_CHANNEL_ROOT_PRE_DIV 348
+#define USB_HSIC_ROOT_PRE_DIV 349
+#define PCIE_CTRL_ROOT_PRE_DIV 350
+#define PCIE_PHY_ROOT_PRE_DIV 351
+#define EPDC_PIXEL_ROOT_PRE_DIV 352
+#define LCDIF_PIXEL_ROOT_PRE_DIV 353
+#define MIPI_DSI_ROOT_PRE_DIV 354
+#define MIPI_CSI_ROOT_PRE_DIV 355
+#define MIPI_DPHY_ROOT_PRE_DIV 356
+#define SAI1_ROOT_PRE_DIV 357
+#define SAI2_ROOT_PRE_DIV 358
+#define SAI3_ROOT_PRE_DIV 359
+#define SPDIF_ROOT_PRE_DIV 360
+#define ENET1_REF_ROOT_PRE_DIV 361
+#define ENET1_TIME_ROOT_PRE_DIV 362
+#define ENET2_REF_ROOT_PRE_DIV 363
+#define ENET2_TIME_ROOT_PRE_DIV 364
+#define ENET_PHY_REF_ROOT_PRE_DIV 365
+#define EIM_ROOT_PRE_DIV 366
+#define NAND_ROOT_PRE_DIV 367
+#define QSPI_ROOT_PRE_DIV 368
+#define USDHC1_ROOT_PRE_DIV 369
+#define USDHC2_ROOT_PRE_DIV 370
+#define USDHC3_ROOT_PRE_DIV 371
+#define CAN1_ROOT_PRE_DIV 372
+#define CAN2_ROOT_PRE_DIV 373
+#define I2C1_ROOT_PRE_DIV 374
+#define I2C2_ROOT_PRE_DIV 375
+#define I2C3_ROOT_PRE_DIV 376
+#define I2C4_ROOT_PRE_DIV 377
+#define UART1_ROOT_PRE_DIV 378
+#define UART2_ROOT_PRE_DIV 379
+#define UART3_ROOT_PRE_DIV 380
+#define UART4_ROOT_PRE_DIV 381
+#define UART5_ROOT_PRE_DIV 382
+#define UART6_ROOT_PRE_DIV 383
+#define UART7_ROOT_PRE_DIV 384
+#define ECSPI1_ROOT_PRE_DIV 385
+#define ECSPI2_ROOT_PRE_DIV 386
+#define ECSPI3_ROOT_PRE_DIV 387
+#define ECSPI4_ROOT_PRE_DIV 388
+#define PWM1_ROOT_PRE_DIV 389
+#define PWM2_ROOT_PRE_DIV 390
+#define PWM3_ROOT_PRE_DIV 391
+#define PWM4_ROOT_PRE_DIV 392
+#define FLEXTIMER1_ROOT_PRE_DIV 393
+#define FLEXTIMER2_ROOT_PRE_DIV 394
+#define SIM1_ROOT_PRE_DIV 395
+#define SIM2_ROOT_PRE_DIV 396
+#define GPT1_ROOT_PRE_DIV 397
+#define GPT2_ROOT_PRE_DIV 398
+#define GPT3_ROOT_PRE_DIV 399
+#define GPT4_ROOT_PRE_DIV 400
+#define TRACE_ROOT_PRE_DIV 401
+#define WDOG_ROOT_PRE_DIV 402
+#define CSI_MCLK_ROOT_PRE_DIV 403
+#define AUDIO_MCLK_ROOT_PRE_DIV 404
+#define WRCLK_ROOT_PRE_DIV 405
+#define CLKO1_ROOT_PRE_DIV 406
+#define CLKO2_ROOT_PRE_DIV 407
+#define DRAM_PHYM_ALT_ROOT_PRE_DIV 408
+#define DRAM_ALT_ROOT_PRE_DIV 409
+#define LVDS1_IN_CLK 410
+#define LVDS1_OUT_SEL 411
+#define LVDS1_OUT_CLK 412
+#define CLK_DUMMY 413
+#define GPT_3M_CLK 414
+#define OCRAM_CLK 415
+#define OCRAM_S_CLK 416
+#define WDOG2_ROOT_CLK 417
+#define WDOG3_ROOT_CLK 418
+#define WDOG4_ROOT_CLK 419
+#define SDMA_CORE_CLK 420
+#define USB1_MAIN_480M_CLK 421
+#define USB_CTRL_CLK 422
+#define USB_PHY1_CLK 423
+#define USB_PHY2_CLK 424
+#define IPG_ROOT_CLK 425
+#define SAI1_IPG_CLK 426
+#define SAI2_IPG_CLK 427
+#define SAI3_IPG_CLK 428
+#define PLL_AUDIO_TEST_DIV 429
+#define PLL_AUDIO_POST_DIV 430
+#define PLL_VIDEO_TEST_DIV 431
+#define PLL_VIDEO_POST_DIV 432
+#define MU_ROOT_CLK 433
+#define SEMA4_HS_ROOT_CLK 434
+#define PLL_DRAM_TEST_DIV 435
+#define ADC_ROOT_CLK 436
+#define CLK_ARM 437
+#define CKIL 438
+#define OCOTP_CLK 439
+#define NAND_RAWNAND_CLK 440
+#define NAND_USDHC_BUS_RAWNAND_CLK 441
+#define SNVS_CLK 442
+#define CAAM_CLK 443
+#define KPP_ROOT_CLK 444
+
+#endif /* !_IMX7D_CCM_H */
Index: src/sys/arch/arm/imx/fdt/imx_ccm_div.c
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx_ccm_div.c:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm_div.c Wed Jun 10 17:57:50 2020
@@ -0,0 +1,124 @@
+/* $NetBSD: imx_ccm_div.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx_ccm_div.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <arm/imx/fdt/imx_ccm.h>
+
+#include <dev/fdt/fdtvar.h>
+
+u_int
+imx_ccm_div_get_rate(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk)
+{
+ struct imx_ccm_div *div = &clk->u.div;
+ struct clk *clkp, *clkp_parent;
+
+ KASSERT(clk->type == IMX_CCM_DIV);
+
+ clkp = &clk->base;
+ clkp_parent = clk_get_parent(clkp);
+ if (clkp_parent == NULL)
+ return 0;
+
+ const u_int prate = clk_get_rate(clkp_parent);
+ if (prate == 0)
+ return 0;
+
+ const uint32_t val = CCM_READ(sc, clk->regidx, div->reg);
+ const u_int n = __SHIFTOUT(val, div->mask);
+
+ return prate / (n + 1);
+}
+
+int
+imx_ccm_div_set_rate(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk, u_int rate)
+{
+ struct imx_ccm_div *div = &clk->u.div;
+ struct clk *clkp, *clkp_parent;
+ int best_diff = INT_MAX;
+ u_int n, best_n;
+ uint32_t val;
+
+ KASSERT(clk->type == IMX_CCM_DIV);
+
+ clkp = &clk->base;
+ clkp_parent = clk_get_parent(clkp);
+ if (clkp_parent == NULL)
+ return ENXIO;
+
+ if ((div->flags & IMX_DIV_SET_RATE_PARENT) != 0)
+ return clk_set_rate(clkp, rate);
+
+ const u_int prate = clk_get_rate(clkp_parent);
+ if (prate == 0)
+ return EIO;
+
+ for (n = 0; n < __SHIFTOUT_MASK(div->mask); n++) {
+ const u_int tmp_rate = prate / (n + 1);
+ const int diff = (int)rate - (int)tmp_rate;
+ if ((div->flags & IMX_DIV_ROUND_DOWN) != 0) {
+ if (diff >= 0 && diff < best_diff) {
+ best_n = n;
+ best_diff = diff;
+ }
+ } else {
+ if (abs(diff) < abs(best_diff)) {
+ best_n = n;
+ best_diff = diff;
+ }
+ }
+ }
+ if (best_diff == INT_MAX)
+ return EIO;
+
+ val = CCM_READ(sc, clk->regidx, div->reg);
+ val &= ~div->mask;
+ val |= __SHIFTIN(best_n, div->mask);
+ CCM_WRITE(sc, clk->regidx, div->reg, val);
+
+ return 0;
+}
+
+const char *
+imx_ccm_div_get_parent(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk)
+{
+ struct imx_ccm_div *div = &clk->u.div;
+
+ KASSERT(clk->type == IMX_CCM_DIV);
+
+ return div->parent;
+}
Index: src/sys/arch/arm/imx/fdt/imx_ccm_mux.c
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx_ccm_mux.c:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm_mux.c Wed Jun 10 17:57:50 2020
@@ -0,0 +1,78 @@
+/* $NetBSD: imx_ccm_mux.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx_ccm_mux.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <arm/imx/fdt/imx_ccm.h>
+
+#include <dev/fdt/fdtvar.h>
+
+const char *
+imx_ccm_mux_get_parent(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk)
+{
+ struct imx_ccm_mux *mux = &clk->u.mux;
+
+ KASSERT(clk->type == IMX_CCM_MUX);
+
+ const uint32_t val = CCM_READ(sc, clk->regidx, mux->reg);
+ const u_int sel = __SHIFTOUT(val, mux->sel);
+
+ if (sel >= mux->nparents)
+ return NULL;
+
+ return mux->parents[sel];
+}
+
+int
+imx_ccm_mux_set_parent(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk, const char *parent)
+{
+ struct imx_ccm_mux *mux = &clk->u.mux;
+ uint32_t val;
+
+ KASSERT(clk->type == IMX_CCM_MUX);
+
+ for (u_int sel = 0; sel < mux->nparents; sel++) {
+ if (strcmp(mux->parents[sel], parent) == 0) {
+ val = CCM_READ(sc, clk->regidx, mux->reg);
+ val &= ~mux->sel;
+ val |= __SHIFTIN(sel, mux->sel);
+ CCM_WRITE(sc, clk->regidx, mux->reg, val);
+ return 0;
+ }
+ }
+
+ return EINVAL;
+}
Index: src/sys/arch/arm/imx/fdt/imx_ccm_pll.c
diff -u /dev/null src/sys/arch/arm/imx/fdt/imx_ccm_pll.c:1.1
--- /dev/null Wed Jun 10 17:57:50 2020
+++ src/sys/arch/arm/imx/fdt/imx_ccm_pll.c Wed Jun 10 17:57:50 2020
@@ -0,0 +1,114 @@
+/* $NetBSD: imx_ccm_pll.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx_ccm_pll.c,v 1.1 2020/06/10 17:57:50 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <arm/imx/fdt/imx_ccm.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#define PLL_POWERDOWN __BIT(12)
+#define PLL_POWERDOWN_ENET __BIT(5)
+
+int
+imx_ccm_pll_enable(struct imx_ccm_softc *sc, struct imx_ccm_clk *clk,
+ int enable)
+{
+ struct imx_ccm_pll *pll = &clk->u.pll;
+ uint32_t val, mask;
+
+ KASSERT(clk->type == IMX_CCM_PLL);
+
+ if ((pll->flags & IMX_PLL_ENET) != 0)
+ mask = PLL_POWERDOWN_ENET;
+ else
+ mask = PLL_POWERDOWN;
+
+ val = CCM_READ(sc, clk->regidx, pll->reg);
+ if (enable)
+ val &= ~mask;
+ else
+ val |= mask;
+ CCM_WRITE(sc, clk->regidx, pll->reg, val);
+
+ return 0;
+}
+
+u_int
+imx_ccm_pll_get_rate(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk)
+{
+ struct imx_ccm_pll *pll= &clk->u.pll;
+ struct clk *clkp, *clkp_parent;
+
+ KASSERT(clk->type == IMX_CCM_PLL);
+
+ clkp = &clk->base;
+ clkp_parent = clk_get_parent(clkp);
+ if (clkp_parent == NULL)
+ return 0;
+
+ const u_int prate = clk_get_rate(clkp_parent);
+ if (prate == 0)
+ return 0;
+
+ if ((pll->flags & IMX_PLL_ENET) != 0) {
+ /* For ENET PLL, div_mask contains the fixed output rate */
+ return pll->div_mask;
+ }
+
+ const uint32_t val = CCM_READ(sc, clk->regidx, pll->reg);
+ const u_int div = __SHIFTOUT(val, pll->div_mask);
+
+ if ((pll->flags & IMX_PLL_ARM) != 0) {
+ return prate * div / 2;
+ }
+
+ if ((pll->flags & IMX_PLL_480M_528M) != 0) {
+ return div == 1 ? 528000000 : 480000000;
+ }
+
+ return 0;
+}
+
+const char *
+imx_ccm_pll_get_parent(struct imx_ccm_softc *sc,
+ struct imx_ccm_clk *clk)
+{
+ struct imx_ccm_pll *pll = &clk->u.pll;
+
+ KASSERT(clk->type == IMX_CCM_PLL);
+
+ return pll->parent;
+}