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;
+}

Reply via email to