2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
5 * Copyright (c) 2018 Greg V <greg@unrelenting.technology>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <machine/bus.h>
42 #include <dev/fdt/simplebus.h>
44 #include <dev/ofw/ofw_bus.h>
45 #include <dev/ofw/ofw_bus_subr.h>
47 #include <dev/extres/clk/clk_div.h>
48 #include <dev/extres/clk/clk_fixed.h>
49 #include <dev/extres/clk/clk_mux.h>
51 #include <arm64/rockchip/clk/rk_cru.h>
55 #define SCLK_USB2PHY0_REF 123
56 #define SCLK_USB2PHY1_REF 124
57 #define SCLK_USB3OTG0_REF 129
58 #define SCLK_USB3OTG1_REF 130
59 #define SCLK_USB3OTG0_SUSPEND 131
60 #define SCLK_USB3OTG1_SUSPEND 132
61 #define ACLK_EMMC_CORE 241
62 #define ACLK_EMMC_NOC 242
63 #define ACLK_EMMC_GRF 243
64 #define ACLK_USB3_NOC 245
65 #define ACLK_USB3OTG0 246
66 #define ACLK_USB3OTG1 247
67 #define ACLK_USB3_RKSOC_AXI_PERF 248
68 #define ACLK_USB3_GRF 249
69 #define PCLK_GPIO2 336
70 #define PCLK_GPIO3 337
71 #define PCLK_GPIO4 338
83 #define HCLK_HOST0 456
84 #define HCLK_HOST0_ARB 457
85 #define HCLK_HOST1 458
86 #define HCLK_HOST1_ARB 459
87 #define HCLK_SDMMC 462
89 static struct rk_cru_gate rk3399_gates[] = {
90 /* CRU_CLKGATE_CON0 */
91 CRU_GATE(0, "clk_core_l_lpll_src", "lpll", 0x300, 0)
92 CRU_GATE(0, "clk_core_l_bpll_src", "bpll", 0x300, 1)
93 CRU_GATE(0, "clk_core_l_dpll_src", "dpll", 0x300, 2)
94 CRU_GATE(0, "clk_core_l_gpll_src", "gpll", 0x300, 3)
96 /* CRU_CLKGATE_CON1 */
97 CRU_GATE(0, "clk_core_b_lpll_src", "lpll", 0x304, 0)
98 CRU_GATE(0, "clk_core_b_bpll_src", "bpll", 0x304, 1)
99 CRU_GATE(0, "clk_core_b_dpll_src", "dpll", 0x304, 2)
100 CRU_GATE(0, "clk_core_b_gpll_src", "gpll", 0x304, 3)
102 /* CRU_CLKGATE_CON5 */
103 CRU_GATE(0, "cpll_aclk_perihp_src", "cpll", 0x314, 0)
104 CRU_GATE(0, "gpll_aclk_perihp_src", "gpll", 0x314, 1)
106 /* CRU_CLKGATE_CON6 */
107 CRU_GATE(0, "gpll_aclk_emmc_src", "gpll", 0x318, 12)
108 CRU_GATE(0, "cpll_aclk_emmc_src", "cpll", 0x318, 13)
109 CRU_GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", 0x318, 5)
110 CRU_GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", 0x318, 6)
112 /* CRU_CLKGATE_CON7 */
113 CRU_GATE(0, "gpll_aclk_perilp0_src", "gpll", 0x31C, 0)
114 CRU_GATE(0, "cpll_aclk_perilp0_src", "cpll", 0x31C, 1)
116 /* CRU_CLKGATE_CON8 */
117 CRU_GATE(0, "hclk_perilp1_cpll_src", "cpll", 0x320, 1)
118 CRU_GATE(0, "hclk_perilp1_gpll_src", "gpll", 0x320, 0)
120 /* CRU_CLKGATE_CON12 */
121 CRU_GATE(SCLK_USB3OTG0_REF, "sclk_usb3otg0_ref", "xin24m", 0x330, 1)
122 CRU_GATE(SCLK_USB3OTG1_REF, "sclk_usb3otg1_ref", "xin24m", 0x330, 2)
123 CRU_GATE(SCLK_USB3OTG0_SUSPEND, "sclk_usb3otg0_suspend", "xin24m", 0x330, 3)
124 CRU_GATE(SCLK_USB3OTG1_SUSPEND, "sclk_usb3otg1_suspend", "xin24m", 0x330, 4)
126 /* CRU_CLKGATE_CON20 */
127 CRU_GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0x350, 5)
128 CRU_GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0x350, 6)
129 CRU_GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", 0x350, 7)
130 CRU_GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", 0x350, 8)
132 /* CRU_CLKGATE_CON22 */
133 CRU_GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0x358, 5)
134 CRU_GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0x358, 6)
135 CRU_GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0x358, 7)
136 CRU_GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0x358, 8)
137 CRU_GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0x358, 9)
138 CRU_GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0x358, 10)
140 /* CRU_CLKGATE_CON23 */
141 CRU_GATE(PCLK_SPI0, "pclk_spi0", "pclk_perilp1", 0x35C, 10)
142 CRU_GATE(PCLK_SPI1, "pclk_spi1", "pclk_perilp1", 0x35C, 11)
143 CRU_GATE(PCLK_SPI2, "pclk_spi2", "pclk_perilp1", 0x35C, 12)
144 CRU_GATE(PCLK_SPI4, "pclk_spi4", "pclk_perilp1", 0x35C, 13)
146 /* CRU_CLKGATE_CON30 */
147 CRU_GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", 0x378, 0)
148 CRU_GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb3", 0x378, 1)
149 CRU_GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb3", 0x378, 2)
150 CRU_GATE(ACLK_USB3_RKSOC_AXI_PERF, "aclk_usb3_rksoc_axi_perf", "aclk_usb3", 0x378, 3)
151 CRU_GATE(ACLK_USB3_GRF, "aclk_usb3_grf", "aclk_usb3", 0x378, 4)
153 /* CRU_CLKGATE_CON31 */
154 CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0x37c, 3)
155 CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0x37c, 4)
156 CRU_GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0x37c, 5)
158 /* CRU_CLKGATE_CON32 */
159 CRU_GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", 0x380, 8)
160 CRU_GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", 0x380, 9)
161 CRU_GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", 0x380, 10)
163 /* CRU_CLKGATE_CON33 */
164 CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0x384, 8)
166 /* CRU_CLKGATE_CON34 */
167 CRU_GATE(PCLK_SPI4, "pclk_spi5", "pclk_perilp1", 0x388, 5)
183 static struct rk_clk_pll_rate rk3399_pll_rates[] = {
803 static const char *pll_parents[] = {"xin24m"};
805 static struct rk_clk_pll_def lpll = {
809 .parent_names = pll_parents,
810 .parent_cnt = nitems(pll_parents),
813 .gate_offset = 0x300,
815 .flags = RK_CLK_PLL_HAVE_GATE,
816 .rates = rk3399_pll_rates,
820 static struct rk_clk_pll_def bpll = {
824 .parent_names = pll_parents,
825 .parent_cnt = nitems(pll_parents),
828 .gate_offset = 0x300,
830 .flags = RK_CLK_PLL_HAVE_GATE,
831 .rates = rk3399_pll_rates,
835 static struct rk_clk_pll_def dpll = {
839 .parent_names = pll_parents,
840 .parent_cnt = nitems(pll_parents),
843 .gate_offset = 0x300,
845 .flags = RK_CLK_PLL_HAVE_GATE,
846 .rates = rk3399_pll_rates,
850 static struct rk_clk_pll_def cpll = {
854 .parent_names = pll_parents,
855 .parent_cnt = nitems(pll_parents),
858 .rates = rk3399_pll_rates,
861 static struct rk_clk_pll_def gpll = {
865 .parent_names = pll_parents,
866 .parent_cnt = nitems(pll_parents),
869 .gate_offset = 0x300,
871 .flags = RK_CLK_PLL_HAVE_GATE,
872 .rates = rk3399_pll_rates,
875 static struct rk_clk_pll_def npll = {
879 .parent_names = pll_parents,
880 .parent_cnt = nitems(pll_parents),
883 .rates = rk3399_pll_rates,
886 static struct rk_clk_pll_def vpll = {
890 .parent_names = pll_parents,
891 .parent_cnt = nitems(pll_parents),
894 .rates = rk3399_pll_rates,
897 #define ACLK_PERIHP 192
898 #define HCLK_PERIHP 448
899 #define PCLK_PERIHP 320
901 static const char *aclk_perihp_parents[] = {"cpll_aclk_perihp_src", "gpll_aclk_perihp_src"};
903 static struct rk_clk_composite_def aclk_perihp = {
906 .name = "aclk_perihp",
907 .parent_names = aclk_perihp_parents,
908 .parent_cnt = nitems(aclk_perihp_parents),
910 /* CRU_CLKSEL_CON14 */
911 .muxdiv_offset = 0x138,
919 /* CRU_CLKGATE_CON5 */
920 .gate_offset = 0x314,
923 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
926 static const char *hclk_pclk_perihp_parents[] = {"aclk_perihp"};
928 static struct rk_clk_composite_def hclk_perihp = {
931 .name = "hclk_perihp",
932 .parent_names = hclk_pclk_perihp_parents,
933 .parent_cnt = nitems(hclk_pclk_perihp_parents),
935 /* CRU_CLKSEL_CON14 */
936 .muxdiv_offset = 0x138,
941 /* CRU_CLKGATE_CON5 */
942 .gate_offset = 0x314,
945 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
948 static struct rk_clk_composite_def pclk_perihp = {
951 .name = "pclk_perihp",
952 .parent_names = hclk_pclk_perihp_parents,
953 .parent_cnt = nitems(hclk_pclk_perihp_parents),
955 /* CRU_CLKSEL_CON14 */
956 .muxdiv_offset = 0x138,
961 /* CRU_CLKGATE_CON5 */
962 .gate_offset = 0x314,
965 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
968 #define ACLK_PERILP0 194
969 #define HCLK_PERILP0 449
970 #define PCLK_PERILP0 322
972 static const char *aclk_perilp0_parents[] = {"cpll_aclk_perilp0_src", "gpll_aclk_perilp0_src"};
974 static struct rk_clk_composite_def aclk_perilp0 = {
977 .name = "aclk_perilp0",
978 .parent_names = aclk_perilp0_parents,
979 .parent_cnt = nitems(aclk_perilp0_parents),
981 /* CRU_CLKSEL_CON14 */
982 .muxdiv_offset = 0x15C,
990 /* CRU_CLKGATE_CON7 */
991 .gate_offset = 0x31C,
994 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
997 static const char *hclk_pclk_perilp0_parents[] = {"aclk_perilp0"};
999 static struct rk_clk_composite_def hclk_perilp0 = {
1002 .name = "hclk_perilp0",
1003 .parent_names = hclk_pclk_perilp0_parents,
1004 .parent_cnt = nitems(hclk_pclk_perilp0_parents),
1006 /* CRU_CLKSEL_CON23 */
1007 .muxdiv_offset = 0x15C,
1012 /* CRU_CLKGATE_CON7 */
1013 .gate_offset = 0x31C,
1016 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1019 static struct rk_clk_composite_def pclk_perilp0 = {
1022 .name = "pclk_perilp0",
1023 .parent_names = hclk_pclk_perilp0_parents,
1024 .parent_cnt = nitems(hclk_pclk_perilp0_parents),
1026 /* CRU_CLKSEL_CON23 */
1027 .muxdiv_offset = 0x15C,
1032 /* CRU_CLKGATE_CON7 */
1033 .gate_offset = 0x31C,
1036 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1042 #define PCLK_ALIVE 390
1044 static const char *alive_parents[] = {"gpll"};
1046 static struct rk_clk_composite_def pclk_alive = {
1049 .name = "pclk_alive",
1050 .parent_names = alive_parents,
1051 .parent_cnt = nitems(alive_parents),
1053 /* CRU_CLKSEL_CON57 */
1054 .muxdiv_offset = 0x01e4,
1060 #define HCLK_PERILP1 450
1061 #define PCLK_PERILP1 323
1063 static const char *hclk_perilp1_parents[] = {"cpll", "gpll"};
1065 static struct rk_clk_composite_def hclk_perilp1 = {
1068 .name = "hclk_perilp1",
1069 .parent_names = hclk_perilp1_parents,
1070 .parent_cnt = nitems(hclk_perilp1_parents),
1072 /* CRU_CLKSEL_CON25 */
1073 .muxdiv_offset = 0x164,
1080 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1083 static const char *pclk_perilp1_parents[] = {"hclk_perilp1"};
1085 static struct rk_clk_composite_def pclk_perilp1 = {
1088 .name = "pclk_perilp1",
1089 .parent_names = pclk_perilp1_parents,
1090 .parent_cnt = nitems(pclk_perilp1_parents),
1092 /* CRU_CLKSEL_CON25 */
1093 .muxdiv_offset = 0x164,
1098 /* CRU_CLKGATE_CON8 */
1099 .gate_offset = 0x320,
1102 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1107 #define ACLK_USB3 244
1108 static const char *aclk_usb3_parents[] = {"cpll", "gpll", "npll", "npll"};
1109 static struct rk_clk_composite_def aclk_usb3 = {
1112 .name = "aclk_usb3",
1113 .parent_names = aclk_usb3_parents,
1114 .parent_cnt = nitems(aclk_usb3_parents),
1116 /* CRU_CLKSET_CON39 */
1117 .muxdiv_offset = 0x19C,
1124 /* CRU_CLKGATE_CON12 */
1125 .gate_offset = 0x330,
1128 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1134 static const char *i2c_parents[] = {"cpll", "gpll"};
1136 #define SCLK_I2C1 65
1137 #define SCLK_I2C2 66
1138 #define SCLK_I2C3 67
1139 #define SCLK_I2C5 68
1140 #define SCLK_I2C6 69
1141 #define SCLK_I2C7 70
1143 static struct rk_clk_composite_def i2c1 = {
1147 .parent_names = i2c_parents,
1148 .parent_cnt = nitems(i2c_parents),
1150 /* CRU_CLKSEL_CON61 */
1151 .muxdiv_offset = 0x01f4,
1158 /* CRU_CLKGATE_CON10 */
1159 .gate_offset = 0x0328,
1162 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1165 static struct rk_clk_composite_def i2c2 = {
1169 .parent_names = i2c_parents,
1170 .parent_cnt = nitems(i2c_parents),
1172 /* CRU_CLKSEL_CON62 */
1173 .muxdiv_offset = 0x01f8,
1180 /* CRU_CLKGATE_CON10 */
1181 .gate_offset = 0x0328,
1184 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1187 static struct rk_clk_composite_def i2c3 = {
1191 .parent_names = i2c_parents,
1192 .parent_cnt = nitems(i2c_parents),
1194 /* CRU_CLKSEL_CON63 */
1195 .muxdiv_offset = 0x01fc,
1202 /* CRU_CLKGATE_CON10 */
1203 .gate_offset = 0x0328,
1206 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1209 static struct rk_clk_composite_def i2c5 = {
1213 .parent_names = i2c_parents,
1214 .parent_cnt = nitems(i2c_parents),
1216 /* CRU_CLKSEL_CON61 */
1217 .muxdiv_offset = 0x01f4,
1224 /* CRU_CLKGATE_CON10 */
1225 .gate_offset = 0x0328,
1228 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1231 static struct rk_clk_composite_def i2c6 = {
1235 .parent_names = i2c_parents,
1236 .parent_cnt = nitems(i2c_parents),
1238 /* CRU_CLKSEL_CON62 */
1239 .muxdiv_offset = 0x01f8,
1246 /* CRU_CLKGATE_CON10 */
1247 .gate_offset = 0x0328,
1250 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1253 static struct rk_clk_composite_def i2c7 = {
1257 .parent_names = i2c_parents,
1258 .parent_cnt = nitems(i2c_parents),
1260 /* CRU_CLKSEL_CON63 */
1261 .muxdiv_offset = 0x01fc,
1268 /* CRU_CLKGATE_CON10 */
1269 .gate_offset = 0x0328,
1272 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1277 #define SCLK_UPHY0_TCPDPHY_REF 125
1278 #define SCLK_UPHY0_TCPDCORE 126
1280 /* Missing xin32k exported by rk808 */
1281 static const char *uphy0_tcpdphy_ref_parents[] = {"xin24m"};
1283 static struct rk_clk_composite_def uphy0_tcpdphy_ref = {
1285 .id = SCLK_UPHY0_TCPDPHY_REF,
1286 .name = "uphy0_tcpdphy_ref",
1287 .parent_names = uphy0_tcpdphy_ref_parents,
1288 .parent_cnt = nitems(uphy0_tcpdphy_ref_parents),
1290 /* CRU_CLKSET_CON64 */
1291 .muxdiv_offset = 0x0200,
1298 /* CRU_CLKGATE_CON13 */
1299 .gate_offset = 0x0334,
1302 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1305 /* Missing xin32k exported by rk808 */
1306 static const char *uphy0_tcpdcore_parents[] = {"xin24m", "xin24m", "cpll", "gpll"};
1308 static struct rk_clk_composite_def uphy0_tcpdcore = {
1310 .id = SCLK_UPHY0_TCPDCORE,
1311 .name = "uphy0_tcpdcore",
1312 .parent_names = uphy0_tcpdcore_parents,
1313 .parent_cnt = nitems(uphy0_tcpdcore_parents),
1315 /* CRU_CLKSET_CON64 */
1316 .muxdiv_offset = 0x0200,
1323 /* CRU_CLKGATE_CON13 */
1324 .gate_offset = 0x0334,
1327 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1330 #define SCLK_UPHY1_TCPDPHY_REF 127
1331 #define SCLK_UPHY1_TCPDCORE 128
1333 /* Missing xin32k exported by rk808 */
1334 static const char *uphy1_tcpdphy_ref_parents[] = {"xin24m"};
1336 static struct rk_clk_composite_def uphy1_tcpdphy_ref = {
1338 .id = SCLK_UPHY1_TCPDPHY_REF,
1339 .name = "uphy1_tcpdphy_ref",
1340 .parent_names = uphy1_tcpdphy_ref_parents,
1341 .parent_cnt = nitems(uphy1_tcpdphy_ref_parents),
1343 /* CRU_CLKSET_CON65 */
1344 .muxdiv_offset = 0x0204,
1351 /* CRU_CLKGATE_CON13 */
1352 .gate_offset = 0x0334,
1355 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1358 /* Missing xin32k exported by rk808 */
1359 static const char *uphy1_tcpdcore_parents[] = {"xin24m", "xin24m", "cpll", "gpll"};
1361 static struct rk_clk_composite_def uphy1_tcpdcore = {
1363 .id = SCLK_UPHY1_TCPDCORE,
1364 .name = "uphy1_tcpdcore",
1365 .parent_names = uphy1_tcpdcore_parents,
1366 .parent_cnt = nitems(uphy1_tcpdcore_parents),
1368 /* CRU_CLKSET_CON65 */
1369 .muxdiv_offset = 0x0204,
1376 /* CRU_CLKGATE_CON13 */
1377 .gate_offset = 0x0334,
1380 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1386 static const char *spi_parents[] = {"cpll", "gpll"};
1388 #define SCLK_SPI0 71
1389 #define SCLK_SPI1 72
1390 #define SCLK_SPI2 73
1391 #define SCLK_SPI4 74
1392 #define SCLK_SPI5 75
1394 static struct rk_clk_composite_def spi0 = {
1398 .parent_names = spi_parents,
1399 .parent_cnt = nitems(spi_parents),
1401 /* CRU_CLKSEL_CON59 */
1402 .muxdiv_offset = 0x01ec,
1409 /* CRU_CLKGATE_CON9 */
1410 .gate_offset = 0x0324,
1413 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1416 static struct rk_clk_composite_def spi1 = {
1420 .parent_names = spi_parents,
1421 .parent_cnt = nitems(spi_parents),
1423 /* CRU_CLKSEL_CON59 */
1424 .muxdiv_offset = 0x01ec,
1431 /* CRU_CLKGATE_CON9 */
1432 .gate_offset = 0x0324,
1435 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1438 static struct rk_clk_composite_def spi2 = {
1442 .parent_names = spi_parents,
1443 .parent_cnt = nitems(spi_parents),
1445 /* CRU_CLKSEL_CON60 */
1446 .muxdiv_offset = 0x01f0,
1453 /* CRU_CLKGATE_CON9 */
1454 .gate_offset = 0x0324,
1457 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1460 static struct rk_clk_composite_def spi4 = {
1464 .parent_names = spi_parents,
1465 .parent_cnt = nitems(spi_parents),
1467 /* CRU_CLKSEL_CON60 */
1468 .muxdiv_offset = 0x01f0,
1475 /* CRU_CLKGATE_CON9 */
1476 .gate_offset = 0x0324,
1479 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1482 static struct rk_clk_composite_def spi5 = {
1486 .parent_names = spi_parents,
1487 .parent_cnt = nitems(spi_parents),
1489 /* CRU_CLKSEL_CON58 */
1490 .muxdiv_offset = 0x01e8,
1497 /* CRU_CLKGATE_CON13 */
1498 .gate_offset = 0x0334,
1501 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1505 * ARM CPU clocks (LITTLE and big)
1510 static const char *armclk_parents[] = {"lpll", "bpll", "dpll", "gpll"};
1512 static struct rk_clk_armclk_rates rk3399_armclkl_rates[] = {
1575 static struct rk_clk_armclk_def armclk_l = {
1579 .parent_names = armclk_parents,
1580 .parent_cnt = nitems(armclk_parents),
1582 /* CRU_CLKSEL_CON0 */
1583 .muxdiv_offset = 0x100,
1590 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1594 .rates = rk3399_armclkl_rates,
1595 .nrates = nitems(rk3399_armclkl_rates),
1598 static struct rk_clk_armclk_rates rk3399_armclkb_rates[] = {
1689 static struct rk_clk_armclk_def armclk_b = {
1693 .parent_names = armclk_parents,
1694 .parent_cnt = nitems(armclk_parents),
1696 .muxdiv_offset = 0x108,
1703 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1707 .rates = rk3399_armclkb_rates,
1708 .nrates = nitems(rk3399_armclkb_rates),
1717 static const char *hclk_sd_parents[] = {"cpll", "gpll"};
1719 static struct rk_clk_composite_def hclk_sd = {
1723 .parent_names = hclk_sd_parents,
1724 .parent_cnt = nitems(hclk_sd_parents),
1727 .muxdiv_offset = 0x134,
1734 .gate_offset = 0x330,
1737 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1740 #define SCLK_SDMMC 76
1742 static const char *sclk_sdmmc_parents[] = {"cpll", "gpll", "npll", "ppll"};
1744 static struct rk_clk_composite_def sclk_sdmmc = {
1747 .name = "sclk_sdmmc",
1748 .parent_names = sclk_sdmmc_parents,
1749 .parent_cnt = nitems(sclk_sdmmc_parents),
1752 .muxdiv_offset = 0x140,
1759 .gate_offset = 0x318,
1762 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1769 #define SCLK_EMMC 78
1771 static const char *sclk_emmc_parents[] = {"cpll", "gpll", "npll"};
1773 static struct rk_clk_composite_def sclk_emmc = {
1776 .name = "sclk_emmc",
1777 .parent_names = sclk_emmc_parents,
1778 .parent_cnt = nitems(sclk_emmc_parents),
1781 .muxdiv_offset = 0x158,
1788 .gate_offset = 0x318,
1791 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1794 #define ACLK_EMMC 240
1796 static const char *aclk_emmc_parents[] = {
1797 "cpll_aclk_emmc_src",
1798 "gpll_aclk_emmc_src"
1801 static struct rk_clk_composite_def aclk_emmc = {
1804 .name = "aclk_emmc",
1805 .parent_names = aclk_emmc_parents,
1806 .parent_cnt = nitems(aclk_emmc_parents),
1809 .muxdiv_offset = 0x154,
1816 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1819 static struct rk_clk rk3399_clks[] = {
1821 .type = RK3399_CLK_PLL,
1825 .type = RK3399_CLK_PLL,
1829 .type = RK3399_CLK_PLL,
1833 .type = RK3399_CLK_PLL,
1837 .type = RK3399_CLK_PLL,
1841 .type = RK3399_CLK_PLL,
1845 .type = RK3399_CLK_PLL,
1850 .type = RK_CLK_COMPOSITE,
1851 .clk.composite = &aclk_perihp,
1854 .type = RK_CLK_COMPOSITE,
1855 .clk.composite = &hclk_perihp,
1858 .type = RK_CLK_COMPOSITE,
1859 .clk.composite = &pclk_perihp,
1862 .type = RK_CLK_COMPOSITE,
1863 .clk.composite = &aclk_perilp0,
1866 .type = RK_CLK_COMPOSITE,
1867 .clk.composite = &hclk_perilp0,
1870 .type = RK_CLK_COMPOSITE,
1871 .clk.composite = &pclk_perilp0,
1874 .type = RK_CLK_COMPOSITE,
1875 .clk.composite = &pclk_alive,
1878 .type = RK_CLK_COMPOSITE,
1879 .clk.composite = &hclk_perilp1,
1882 .type = RK_CLK_COMPOSITE,
1883 .clk.composite = &pclk_perilp1,
1886 .type = RK_CLK_COMPOSITE,
1887 .clk.composite = &aclk_usb3,
1890 .type = RK_CLK_COMPOSITE,
1891 .clk.composite = &i2c1,
1894 .type = RK_CLK_COMPOSITE,
1895 .clk.composite = &i2c2,
1898 .type = RK_CLK_COMPOSITE,
1899 .clk.composite = &i2c3,
1902 .type = RK_CLK_COMPOSITE,
1903 .clk.composite = &i2c5,
1906 .type = RK_CLK_COMPOSITE,
1907 .clk.composite = &i2c6,
1910 .type = RK_CLK_COMPOSITE,
1911 .clk.composite = &i2c7,
1914 .type = RK_CLK_COMPOSITE,
1915 .clk.composite = &uphy0_tcpdphy_ref,
1918 .type = RK_CLK_COMPOSITE,
1919 .clk.composite = &uphy0_tcpdcore,
1922 .type = RK_CLK_COMPOSITE,
1923 .clk.composite = &uphy1_tcpdphy_ref,
1926 .type = RK_CLK_COMPOSITE,
1927 .clk.composite = &uphy1_tcpdcore,
1931 .type = RK_CLK_COMPOSITE,
1932 .clk.composite = &spi0,
1935 .type = RK_CLK_COMPOSITE,
1936 .clk.composite = &spi1,
1939 .type = RK_CLK_COMPOSITE,
1940 .clk.composite = &spi2,
1943 .type = RK_CLK_COMPOSITE,
1944 .clk.composite = &spi4,
1947 .type = RK_CLK_COMPOSITE,
1948 .clk.composite = &spi5,
1952 .type = RK_CLK_ARMCLK,
1953 .clk.armclk = &armclk_l,
1956 .type = RK_CLK_ARMCLK,
1957 .clk.armclk = &armclk_b,
1961 .type = RK_CLK_COMPOSITE,
1962 .clk.composite = &hclk_sd,
1965 .type = RK_CLK_COMPOSITE,
1966 .clk.composite = &sclk_sdmmc,
1970 .type = RK_CLK_COMPOSITE,
1971 .clk.composite = &sclk_emmc,
1974 .type = RK_CLK_COMPOSITE,
1975 .clk.composite = &aclk_emmc,
1980 rk3399_cru_probe(device_t dev)
1983 if (!ofw_bus_status_okay(dev))
1986 if (ofw_bus_is_compatible(dev, "rockchip,rk3399-cru")) {
1987 device_set_desc(dev, "Rockchip RK3399 Clock and Reset Unit");
1988 return (BUS_PROBE_DEFAULT);
1995 rk3399_cru_attach(device_t dev)
1997 struct rk_cru_softc *sc;
1999 sc = device_get_softc(dev);
2002 sc->gates = rk3399_gates;
2003 sc->ngates = nitems(rk3399_gates);
2005 sc->clks = rk3399_clks;
2006 sc->nclks = nitems(rk3399_clks);
2008 sc->reset_offset = 0x400;
2009 sc->reset_num = 335;
2011 return (rk_cru_attach(dev));
2014 static device_method_t rk3399_cru_methods[] = {
2015 /* Device interface */
2016 DEVMETHOD(device_probe, rk3399_cru_probe),
2017 DEVMETHOD(device_attach, rk3399_cru_attach),
2022 static devclass_t rk3399_cru_devclass;
2024 DEFINE_CLASS_1(rk3399_cru, rk3399_cru_driver, rk3399_cru_methods,
2025 sizeof(struct rk_cru_softc), rk_cru_driver);
2027 EARLY_DRIVER_MODULE(rk3399_cru, simplebus, rk3399_cru_driver,
2028 rk3399_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);