summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-11-07 21:42:47 +0000
committerpatrick <patrick@openbsd.org>2020-11-07 21:42:47 +0000
commit22a4f870dd4081463b45d47ad63aed7bea7543d3 (patch)
tree2b9d46446b1e61d11e5b4f67b72d032ca88e0e8f
parentImplement 'from dynamic', which installs flows where 'dynamic' is replaced (diff)
downloadwireguard-openbsd-22a4f870dd4081463b45d47ad63aed7bea7543d3.tar.xz
wireguard-openbsd-22a4f870dd4081463b45d47ad63aed7bea7543d3.zip
Add clock support for i.MX8MP. This variant uses essentially the
same layout as the i.MX8MM, which means that all supported clocks so far have the same selection of parents and allows reusing the i.MX8MM code.
-rw-r--r--sys/dev/fdt/imxccm.c54
-rw-r--r--sys/dev/fdt/imxccm_clocks.h145
2 files changed, 198 insertions, 1 deletions
diff --git a/sys/dev/fdt/imxccm.c b/sys/dev/fdt/imxccm.c
index 91301606e86..91253a01350 100644
--- a/sys/dev/fdt/imxccm.c
+++ b/sys/dev/fdt/imxccm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxccm.c,v 1.22 2020/10/12 17:38:28 patrick Exp $ */
+/* $OpenBSD: imxccm.c,v 1.23 2020/11/07 21:42:47 patrick Exp $ */
/*
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
*
@@ -273,6 +273,7 @@ imxccm_match(struct device *parent, void *match, void *aux)
OF_is_compatible(faa->fa_node, "fsl,imx6ul-ccm") ||
OF_is_compatible(faa->fa_node, "fsl,imx7d-ccm") ||
OF_is_compatible(faa->fa_node, "fsl,imx8mm-ccm") ||
+ OF_is_compatible(faa->fa_node, "fsl,imx8mp-ccm") ||
OF_is_compatible(faa->fa_node, "fsl,imx8mq-ccm"));
}
@@ -303,6 +304,17 @@ imxccm_attach(struct device *parent, struct device *self, void *aux)
sc->sc_nmuxs = nitems(imx8mm_muxs);
sc->sc_predivs = imx8mm_predivs;
sc->sc_npredivs = nitems(imx8mm_predivs);
+ } else if (OF_is_compatible(sc->sc_node, "fsl,imx8mp-ccm")) {
+ sc->sc_anatop = regmap_bycompatible("fsl,imx8mp-anatop");
+ KASSERT(sc->sc_anatop != NULL);
+ sc->sc_gates = imx8mp_gates;
+ sc->sc_ngates = nitems(imx8mp_gates);
+ sc->sc_divs = imx8mp_divs;
+ sc->sc_ndivs = nitems(imx8mp_divs);
+ sc->sc_muxs = imx8mp_muxs;
+ sc->sc_nmuxs = nitems(imx8mp_muxs);
+ sc->sc_predivs = imx8mp_predivs;
+ sc->sc_npredivs = nitems(imx8mp_predivs);
} else if (OF_is_compatible(sc->sc_node, "fsl,imx8mq-ccm")) {
sc->sc_anatop = regmap_bycompatible("fsl,imx8mq-anatop");
KASSERT(sc->sc_anatop != NULL);
@@ -1479,6 +1491,46 @@ imxccm_get_frequency(void *cookie, uint32_t *cells)
pre = pre & sc->sc_predivs[idx].mask;
return ((freq / (pre + 1)) / (div + 1));
}
+ } else if (sc->sc_gates == imx8mp_gates) {
+ /* These are composite clocks. */
+ if (idx < sc->sc_ngates && sc->sc_gates[idx].reg &&
+ idx < sc->sc_ndivs && sc->sc_divs[idx].reg &&
+ idx < sc->sc_npredivs && sc->sc_predivs[idx].reg) {
+ switch (idx) {
+ case IMX8MP_CLK_ENET_AXI:
+ freq = imxccm_imx8mm_enet(sc, idx);
+ break;
+ case IMX8MP_CLK_I2C1:
+ case IMX8MP_CLK_I2C2:
+ case IMX8MP_CLK_I2C3:
+ case IMX8MP_CLK_I2C4:
+ case IMX8MP_CLK_I2C5:
+ case IMX8MP_CLK_I2C6:
+ freq = imxccm_imx8mm_i2c(sc, idx);
+ break;
+ case IMX8MP_CLK_UART1:
+ case IMX8MP_CLK_UART2:
+ case IMX8MP_CLK_UART3:
+ case IMX8MP_CLK_UART4:
+ freq = imxccm_imx8mm_uart(sc, idx);
+ break;
+ case IMX8MP_CLK_USDHC1:
+ case IMX8MP_CLK_USDHC2:
+ case IMX8MP_CLK_USDHC3:
+ freq = imxccm_imx8mm_usdhc(sc, idx);
+ break;
+ default:
+ printf("%s: 0x%08x\n", __func__, idx);
+ return 0;
+ }
+
+ reg = HREAD4(sc, sc->sc_divs[idx].reg);
+ div = reg >> sc->sc_divs[idx].shift;
+ div = div & sc->sc_divs[idx].mask;
+ pre = reg >> sc->sc_predivs[idx].shift;
+ pre = pre & sc->sc_predivs[idx].mask;
+ return ((freq / (pre + 1)) / (div + 1));
+ }
} else if (sc->sc_gates == imx8mq_gates) {
switch (idx) {
case IMX8MQ_CLK_ARM:
diff --git a/sys/dev/fdt/imxccm_clocks.h b/sys/dev/fdt/imxccm_clocks.h
index b149b8e68f5..8c5da8091f4 100644
--- a/sys/dev/fdt/imxccm_clocks.h
+++ b/sys/dev/fdt/imxccm_clocks.h
@@ -474,6 +474,151 @@ struct imxccm_mux imx8mm_muxs[] = {
};
/*
+ * i.MX8MP clocks.
+ */
+
+#define IMX8MP_SYS_PLL1_266M 0x36
+#define IMX8MP_SYS_PLL2_100M 0x3a
+#define IMX8MP_SYS_PLL2_125M 0x3b
+#define IMX8MP_CLK_ENET_AXI 0x5e
+#define IMX8MP_CLK_NAND_USDHC_BUS 0x5f
+#define IMX8MP_CLK_I2C5 0x79
+#define IMX8MP_CLK_I2C6 0x7a
+#define IMX8MP_CLK_ENET_QOS 0x81
+#define IMX8MP_CLK_ENET_QOS_TIMER 0x82
+#define IMX8MP_CLK_ENET_REF 0x83
+#define IMX8MP_CLK_ENET_TIMER 0x84
+#define IMX8MP_CLK_ENET_PHY_REF 0x85
+#define IMX8MP_CLK_USDHC1 0x88
+#define IMX8MP_CLK_USDHC2 0x89
+#define IMX8MP_CLK_I2C1 0x8a
+#define IMX8MP_CLK_I2C2 0x8b
+#define IMX8MP_CLK_I2C3 0x8c
+#define IMX8MP_CLK_I2C4 0x8d
+#define IMX8MP_CLK_UART1 0x8e
+#define IMX8MP_CLK_UART2 0x8f
+#define IMX8MP_CLK_UART3 0x90
+#define IMX8MP_CLK_UART4 0x91
+#define IMX8MP_CLK_ENET1_ROOT 0xc0
+#define IMX8MP_CLK_I2C1_ROOT 0xcd
+#define IMX8MP_CLK_I2C2_ROOT 0xce
+#define IMX8MP_CLK_I2C3_ROOT 0xcf
+#define IMX8MP_CLK_I2C4_ROOT 0xd0
+#define IMX8MP_CLK_QOS_ROOT 0xe0
+#define IMX8MP_CLK_QOS_ENET_ROOT 0xe1
+#define IMX8MP_CLK_I2C5_ROOT 0xe7
+#define IMX8MP_CLK_I2C6_ROOT 0xe8
+#define IMX8MP_CLK_ENET_QOS_ROOT 0xed
+#define IMX8MP_CLK_SIM_ENET_ROOT 0xf2
+#define IMX8MP_CLK_UART1_ROOT 0xfb
+#define IMX8MP_CLK_UART2_ROOT 0xfc
+#define IMX8MP_CLK_UART3_ROOT 0xfd
+#define IMX8MP_CLK_UART4_ROOT 0xfe
+#define IMX8MP_CLK_USDHC3 0xa9
+#define IMX8MP_CLK_USDHC1_ROOT 0x101
+#define IMX8MP_CLK_USDHC2_ROOT 0x102
+#define IMX8MP_CLK_USDHC3_ROOT 0x115
+
+struct imxccm_gate imx8mp_gates[] = {
+ [IMX8MP_CLK_ENET_AXI] = { 0x8880, 14 },
+ [IMX8MP_CLK_NAND_USDHC_BUS] = { 0x8900, 14 },
+ [IMX8MP_CLK_I2C5] = { 0xa480, 14 },
+ [IMX8MP_CLK_I2C6] = { 0xa500, 14 },
+ [IMX8MP_CLK_ENET_REF] = { 0xa980, 14 },
+ [IMX8MP_CLK_ENET_TIMER] = { 0xaa00, 14 },
+ [IMX8MP_CLK_ENET_PHY_REF] = { 0xaa80, 14 },
+ [IMX8MP_CLK_USDHC1] = { 0xac00, 14 },
+ [IMX8MP_CLK_USDHC2] = { 0xac80, 14 },
+ [IMX8MP_CLK_I2C1] = { 0xad00, 14 },
+ [IMX8MP_CLK_I2C2] = { 0xad80, 14 },
+ [IMX8MP_CLK_I2C3] = { 0xae00, 14 },
+ [IMX8MP_CLK_I2C4] = { 0xae80, 14 },
+ [IMX8MP_CLK_UART1] = { 0xaf00, 14 },
+ [IMX8MP_CLK_UART2] = { 0xaf80, 14 },
+ [IMX8MP_CLK_UART3] = { 0xb000, 14 },
+ [IMX8MP_CLK_UART4] = { 0xb080, 14 },
+ [IMX8MP_CLK_USDHC3] = { 0xbc80, 14 },
+ [IMX8MP_CLK_ENET1_ROOT] = { 0x40a0, 0, IMX8MP_CLK_ENET_AXI },
+ [IMX8MP_CLK_I2C1_ROOT] = { 0x4170, 0, IMX8MP_CLK_I2C1 },
+ [IMX8MP_CLK_I2C2_ROOT] = { 0x4180, 0, IMX8MP_CLK_I2C2 },
+ [IMX8MP_CLK_I2C3_ROOT] = { 0x4190, 0, IMX8MP_CLK_I2C3 },
+ [IMX8MP_CLK_I2C4_ROOT] = { 0x41a0, 0, IMX8MP_CLK_I2C4 },
+ [IMX8MP_CLK_I2C5_ROOT] = { 0x4330, 0, IMX8MP_CLK_I2C5 },
+ [IMX8MP_CLK_I2C6_ROOT] = { 0x4340, 0, IMX8MP_CLK_I2C6 },
+ [IMX8MP_CLK_SIM_ENET_ROOT] = { 0x4400, 0, IMX8MP_CLK_ENET_AXI },
+ [IMX8MP_CLK_UART1_ROOT] = { 0x4490, 0, IMX8MP_CLK_UART1 },
+ [IMX8MP_CLK_UART2_ROOT] = { 0x44a0, 0, IMX8MP_CLK_UART2 },
+ [IMX8MP_CLK_UART3_ROOT] = { 0x44b0, 0, IMX8MP_CLK_UART3 },
+ [IMX8MP_CLK_UART4_ROOT] = { 0x44c0, 0, IMX8MP_CLK_UART4 },
+ [IMX8MP_CLK_USDHC1_ROOT] = { 0x4510, 0, IMX8MP_CLK_USDHC1 },
+ [IMX8MP_CLK_USDHC2_ROOT] = { 0x4520, 0, IMX8MP_CLK_USDHC2 },
+ [IMX8MP_CLK_USDHC3_ROOT] = { 0x45e0, 0, IMX8MP_CLK_USDHC3 },
+};
+
+struct imxccm_divider imx8mp_divs[] = {
+ [IMX8MP_CLK_ENET_AXI] = { 0x8880, 0, 0x3f },
+ [IMX8MP_CLK_NAND_USDHC_BUS] = { 0x8900, 0, 0x3f },
+ [IMX8MP_CLK_I2C5] = { 0xa480, 0, 0x3f },
+ [IMX8MP_CLK_I2C6] = { 0xa500, 0, 0x3f },
+ [IMX8MP_CLK_ENET_REF] = { 0xa980, 0, 0x3f },
+ [IMX8MP_CLK_ENET_TIMER] = { 0xaa00, 0, 0x3f },
+ [IMX8MP_CLK_ENET_PHY_REF] = { 0xaa80, 0, 0x3f},
+ [IMX8MP_CLK_USDHC1] = { 0xac00, 0, 0x3f },
+ [IMX8MP_CLK_USDHC2] = { 0xac80, 0, 0x3f },
+ [IMX8MP_CLK_I2C1] = { 0xad00, 0, 0x3f },
+ [IMX8MP_CLK_I2C2] = { 0xad80, 0, 0x3f },
+ [IMX8MP_CLK_I2C3] = { 0xae00, 0, 0x3f },
+ [IMX8MP_CLK_I2C4] = { 0xae80, 0, 0x3f },
+ [IMX8MP_CLK_UART1] = { 0xaf00, 0, 0x3f },
+ [IMX8MP_CLK_UART2] = { 0xaf80, 0, 0x3f },
+ [IMX8MP_CLK_UART3] = { 0xb000, 0, 0x3f },
+ [IMX8MP_CLK_UART4] = { 0xb080, 0, 0x3f },
+ [IMX8MP_CLK_USDHC3] = { 0xbc80, 0, 0x3f },
+};
+
+struct imxccm_divider imx8mp_predivs[] = {
+ [IMX8MP_CLK_ENET_AXI] = { 0x8880, 16, 0x7 },
+ [IMX8MP_CLK_NAND_USDHC_BUS] = { 0x8900, 16, 0x7 },
+ [IMX8MP_CLK_I2C5] = { 0xa480, 16, 0x7 },
+ [IMX8MP_CLK_I2C6] = { 0xa500, 16, 0x7 },
+ [IMX8MP_CLK_ENET_REF] = { 0xa980, 16, 0x7 },
+ [IMX8MP_CLK_ENET_TIMER] = { 0xaa00, 16, 0x7 },
+ [IMX8MP_CLK_ENET_PHY_REF] = { 0xaa80, 16, 0x7 },
+ [IMX8MP_CLK_USDHC1] = { 0xac00, 16, 0x7 },
+ [IMX8MP_CLK_USDHC2] = { 0xac80, 16, 0x7 },
+ [IMX8MP_CLK_I2C1] = { 0xad00, 16, 0x7 },
+ [IMX8MP_CLK_I2C2] = { 0xad80, 16, 0x7 },
+ [IMX8MP_CLK_I2C3] = { 0xae00, 16, 0x7 },
+ [IMX8MP_CLK_I2C4] = { 0xae80, 16, 0x7 },
+ [IMX8MP_CLK_UART1] = { 0xaf00, 16, 0x7 },
+ [IMX8MP_CLK_UART2] = { 0xaf80, 16, 0x7 },
+ [IMX8MP_CLK_UART3] = { 0xb000, 16, 0x7 },
+ [IMX8MP_CLK_UART4] = { 0xb080, 16, 0x7 },
+ [IMX8MP_CLK_USDHC3] = { 0xbc80, 16, 0x7 },
+};
+
+struct imxccm_mux imx8mp_muxs[] = {
+ [IMX8MP_CLK_ENET_AXI] = { 0x8880, 24, 0x7 },
+ [IMX8MP_CLK_NAND_USDHC_BUS] = { 0x8900, 24, 0x7 },
+ [IMX8MP_CLK_I2C5] = { 0xa480, 24, 0x7 },
+ [IMX8MP_CLK_I2C6] = { 0xa500, 24, 0x7 },
+ [IMX8MP_CLK_ENET_REF] = { 0xa980, 24, 0x7 },
+ [IMX8MP_CLK_ENET_TIMER] = { 0xaa00, 24, 0x7 },
+ [IMX8MP_CLK_ENET_PHY_REF] = { 0xaa80, 24, 0x7 },
+ [IMX8MP_CLK_USDHC1] = { 0xac00, 24, 0x7 },
+ [IMX8MP_CLK_USDHC2] = { 0xac80, 24, 0x7 },
+ [IMX8MP_CLK_I2C1] = { 0xad00, 24, 0x7 },
+ [IMX8MP_CLK_I2C2] = { 0xad80, 24, 0x7 },
+ [IMX8MP_CLK_I2C3] = { 0xae00, 24, 0x7 },
+ [IMX8MP_CLK_I2C4] = { 0xae80, 24, 0x7 },
+ [IMX8MP_CLK_UART1] = { 0xaf00, 24, 0x7 },
+ [IMX8MP_CLK_UART2] = { 0xaf80, 24, 0x7 },
+ [IMX8MP_CLK_UART3] = { 0xb000, 24, 0x7 },
+ [IMX8MP_CLK_UART4] = { 0xb080, 24, 0x7 },
+ [IMX8MP_CLK_USDHC3] = { 0xbc80, 24, 0x7 },
+};
+
+/*
* i.MX8MQ clocks.
*/