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 ACLK_EMMC_CORE 241
58 #define ACLK_EMMC_NOC 242
59 #define ACLK_EMMC_GRF 243
60 #define PCLK_GPIO2 336
61 #define PCLK_GPIO3 337
62 #define PCLK_GPIO4 338
69 #define HCLK_HOST0 456
70 #define HCLK_HOST0_ARB 457
71 #define HCLK_HOST1 458
72 #define HCLK_HOST1_ARB 459
73 #define HCLK_SDMMC 462
75 static struct rk_cru_gate rk3399_gates[] = {
76 /* CRU_CLKGATE_CON0 */
77 CRU_GATE(0, "clk_core_l_lpll_src", "lpll", 0x300, 0)
78 CRU_GATE(0, "clk_core_l_bpll_src", "bpll", 0x300, 1)
79 CRU_GATE(0, "clk_core_l_dpll_src", "dpll", 0x300, 2)
80 CRU_GATE(0, "clk_core_l_gpll_src", "gpll", 0x300, 3)
82 /* CRU_CLKGATE_CON1 */
83 CRU_GATE(0, "clk_core_b_lpll_src", "lpll", 0x304, 0)
84 CRU_GATE(0, "clk_core_b_bpll_src", "bpll", 0x304, 1)
85 CRU_GATE(0, "clk_core_b_dpll_src", "dpll", 0x304, 2)
86 CRU_GATE(0, "clk_core_b_gpll_src", "gpll", 0x304, 3)
88 /* CRU_CLKGATE_CON5 */
89 CRU_GATE(0, "cpll_aclk_perihp_src", "cpll", 0x314, 0)
90 CRU_GATE(0, "gpll_aclk_perihp_src", "gpll", 0x314, 1)
92 /* CRU_CLKGATE_CON6 */
93 CRU_GATE(0, "gpll_aclk_emmc_src", "gpll", 0x318, 12)
94 CRU_GATE(0, "cpll_aclk_emmc_src", "cpll", 0x318, 13)
95 CRU_GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", 0x318, 5)
96 CRU_GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", 0x318, 6)
98 /* CRU_CLKGATE_CON7 */
99 CRU_GATE(0, "gpll_aclk_perilp0_src", "gpll", 0x31C, 0)
100 CRU_GATE(0, "cpll_aclk_perilp0_src", "cpll", 0x31C, 1)
102 /* CRU_CLKGATE_CON8 */
103 CRU_GATE(0, "hclk_perilp1_cpll_src", "cpll", 0x320, 1)
104 CRU_GATE(0, "hclk_perilp1_gpll_src", "gpll", 0x320, 0)
106 /* CRU_CLKGATE_CON20 */
107 CRU_GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0x350, 5)
108 CRU_GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0x350, 6)
109 CRU_GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", 0x350, 7)
110 CRU_GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", 0x350, 8)
112 /* CRU_CLKGATE_CON22 */
113 CRU_GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0x358, 5)
114 CRU_GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0x358, 6)
115 CRU_GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0x358, 7)
116 CRU_GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0x358, 8)
117 CRU_GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0x358, 9)
118 CRU_GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0x358, 10)
120 /* CRU_CLKGATE_CON31 */
121 CRU_GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0x37c, 3)
122 CRU_GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0x37c, 4)
123 CRU_GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0x37c, 5)
125 /* CRU_CLKGATE_CON32 */
126 CRU_GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", 0x380, 8)
127 CRU_GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", 0x380, 9)
128 CRU_GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", 0x380, 10)
130 /* CRU_CLKGATE_CON33 */
131 CRU_GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0x384, 8)
147 static struct rk_clk_pll_rate rk3399_pll_rates[] = {
767 static const char *pll_parents[] = {"xin24m"};
769 static struct rk_clk_pll_def lpll = {
773 .parent_names = pll_parents,
774 .parent_cnt = nitems(pll_parents),
777 .gate_offset = 0x300,
779 .flags = RK_CLK_PLL_HAVE_GATE,
780 .rates = rk3399_pll_rates,
784 static struct rk_clk_pll_def bpll = {
788 .parent_names = pll_parents,
789 .parent_cnt = nitems(pll_parents),
792 .gate_offset = 0x300,
794 .flags = RK_CLK_PLL_HAVE_GATE,
795 .rates = rk3399_pll_rates,
799 static struct rk_clk_pll_def dpll = {
803 .parent_names = pll_parents,
804 .parent_cnt = nitems(pll_parents),
807 .gate_offset = 0x300,
809 .flags = RK_CLK_PLL_HAVE_GATE,
810 .rates = rk3399_pll_rates,
814 static struct rk_clk_pll_def cpll = {
818 .parent_names = pll_parents,
819 .parent_cnt = nitems(pll_parents),
822 .rates = rk3399_pll_rates,
825 static struct rk_clk_pll_def gpll = {
829 .parent_names = pll_parents,
830 .parent_cnt = nitems(pll_parents),
833 .gate_offset = 0x300,
835 .flags = RK_CLK_PLL_HAVE_GATE,
836 .rates = rk3399_pll_rates,
839 static struct rk_clk_pll_def npll = {
843 .parent_names = pll_parents,
844 .parent_cnt = nitems(pll_parents),
847 .rates = rk3399_pll_rates,
850 static struct rk_clk_pll_def vpll = {
854 .parent_names = pll_parents,
855 .parent_cnt = nitems(pll_parents),
858 .rates = rk3399_pll_rates,
861 #define ACLK_PERIHP 192
862 #define HCLK_PERIHP 448
863 #define PCLK_PERIHP 320
865 static const char *aclk_perihp_parents[] = {"cpll_aclk_perihp_src", "gpll_aclk_perihp_src"};
867 static struct rk_clk_composite_def aclk_perihp = {
870 .name = "aclk_perihp",
871 .parent_names = aclk_perihp_parents,
872 .parent_cnt = nitems(aclk_perihp_parents),
874 /* CRU_CLKSEL_CON14 */
875 .muxdiv_offset = 0x138,
883 /* CRU_CLKGATE_CON5 */
884 .gate_offset = 0x314,
887 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
890 static const char *hclk_pclk_perihp_parents[] = {"aclk_perihp"};
892 static struct rk_clk_composite_def hclk_perihp = {
895 .name = "hclk_perihp",
896 .parent_names = hclk_pclk_perihp_parents,
897 .parent_cnt = nitems(hclk_pclk_perihp_parents),
899 /* CRU_CLKSEL_CON14 */
900 .muxdiv_offset = 0x138,
905 /* CRU_CLKGATE_CON5 */
906 .gate_offset = 0x314,
909 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
912 static struct rk_clk_composite_def pclk_perihp = {
915 .name = "pclk_perihp",
916 .parent_names = hclk_pclk_perihp_parents,
917 .parent_cnt = nitems(hclk_pclk_perihp_parents),
919 /* CRU_CLKSEL_CON14 */
920 .muxdiv_offset = 0x138,
925 /* CRU_CLKGATE_CON5 */
926 .gate_offset = 0x314,
929 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
932 #define ACLK_PERILP0 194
933 #define HCLK_PERILP0 449
934 #define PCLK_PERILP0 322
936 static const char *aclk_perilp0_parents[] = {"cpll_aclk_perilp0_src", "gpll_aclk_perilp0_src"};
938 static struct rk_clk_composite_def aclk_perilp0 = {
941 .name = "aclk_perilp0",
942 .parent_names = aclk_perilp0_parents,
943 .parent_cnt = nitems(aclk_perilp0_parents),
945 /* CRU_CLKSEL_CON14 */
946 .muxdiv_offset = 0x15C,
954 /* CRU_CLKGATE_CON7 */
955 .gate_offset = 0x31C,
958 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
961 static const char *hclk_pclk_perilp0_parents[] = {"aclk_perilp0"};
963 static struct rk_clk_composite_def hclk_perilp0 = {
966 .name = "hclk_perilp0",
967 .parent_names = hclk_pclk_perilp0_parents,
968 .parent_cnt = nitems(hclk_pclk_perilp0_parents),
970 /* CRU_CLKSEL_CON23 */
971 .muxdiv_offset = 0x15C,
976 /* CRU_CLKGATE_CON7 */
977 .gate_offset = 0x31C,
980 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
983 static struct rk_clk_composite_def pclk_perilp0 = {
986 .name = "pclk_perilp0",
987 .parent_names = hclk_pclk_perilp0_parents,
988 .parent_cnt = nitems(hclk_pclk_perilp0_parents),
990 /* CRU_CLKSEL_CON23 */
991 .muxdiv_offset = 0x15C,
996 /* CRU_CLKGATE_CON7 */
997 .gate_offset = 0x31C,
1000 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1006 #define PCLK_ALIVE 390
1008 static const char *alive_parents[] = {"gpll"};
1010 static struct rk_clk_composite_def pclk_alive = {
1013 .name = "pclk_alive",
1014 .parent_names = alive_parents,
1015 .parent_cnt = nitems(alive_parents),
1017 /* CRU_CLKSEL_CON57 */
1018 .muxdiv_offset = 0x01e4,
1024 #define HCLK_PERILP1 450
1025 #define PCLK_PERILP1 323
1027 static const char *hclk_perilp1_parents[] = {"cpll", "gpll"};
1029 static struct rk_clk_composite_def hclk_perilp1 = {
1032 .name = "hclk_perilp1",
1033 .parent_names = hclk_perilp1_parents,
1034 .parent_cnt = nitems(hclk_perilp1_parents),
1036 /* CRU_CLKSEL_CON25 */
1037 .muxdiv_offset = 0x164,
1044 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1047 static const char *pclk_perilp1_parents[] = {"hclk_perilp1"};
1049 static struct rk_clk_composite_def pclk_perilp1 = {
1052 .name = "pclk_perilp1",
1053 .parent_names = pclk_perilp1_parents,
1054 .parent_cnt = nitems(pclk_perilp1_parents),
1056 /* CRU_CLKSEL_CON25 */
1057 .muxdiv_offset = 0x164,
1062 /* CRU_CLKGATE_CON8 */
1063 .gate_offset = 0x320,
1066 .flags = RK_CLK_COMPOSITE_HAVE_GATE,
1072 static const char *i2c_parents[] = {"cpll", "gpll"};
1074 #define SCLK_I2C1 65
1075 #define SCLK_I2C2 66
1076 #define SCLK_I2C3 67
1077 #define SCLK_I2C5 68
1078 #define SCLK_I2C6 69
1079 #define SCLK_I2C7 70
1081 static struct rk_clk_composite_def i2c1 = {
1085 .parent_names = i2c_parents,
1086 .parent_cnt = nitems(i2c_parents),
1088 /* CRU_CLKSEL_CON61 */
1089 .muxdiv_offset = 0x01f4,
1096 /* CRU_CLKGATE_CON10 */
1097 .gate_offset = 0x0328,
1100 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1103 static struct rk_clk_composite_def i2c2 = {
1107 .parent_names = i2c_parents,
1108 .parent_cnt = nitems(i2c_parents),
1110 /* CRU_CLKSEL_CON62 */
1111 .muxdiv_offset = 0x01f8,
1118 /* CRU_CLKGATE_CON10 */
1119 .gate_offset = 0x0328,
1122 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1125 static struct rk_clk_composite_def i2c3 = {
1129 .parent_names = i2c_parents,
1130 .parent_cnt = nitems(i2c_parents),
1132 /* CRU_CLKSEL_CON63 */
1133 .muxdiv_offset = 0x01fc,
1140 /* CRU_CLKGATE_CON10 */
1141 .gate_offset = 0x0328,
1144 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1147 static struct rk_clk_composite_def i2c5 = {
1151 .parent_names = i2c_parents,
1152 .parent_cnt = nitems(i2c_parents),
1154 /* CRU_CLKSEL_CON61 */
1155 .muxdiv_offset = 0x01f4,
1162 /* CRU_CLKGATE_CON10 */
1163 .gate_offset = 0x0328,
1166 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1169 static struct rk_clk_composite_def i2c6 = {
1173 .parent_names = i2c_parents,
1174 .parent_cnt = nitems(i2c_parents),
1176 /* CRU_CLKSEL_CON62 */
1177 .muxdiv_offset = 0x01f8,
1184 /* CRU_CLKGATE_CON10 */
1185 .gate_offset = 0x0328,
1188 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1191 static struct rk_clk_composite_def i2c7 = {
1195 .parent_names = i2c_parents,
1196 .parent_cnt = nitems(i2c_parents),
1198 /* CRU_CLKSEL_CON63 */
1199 .muxdiv_offset = 0x01fc,
1206 /* CRU_CLKGATE_CON10 */
1207 .gate_offset = 0x0328,
1210 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1214 * ARM CPU clocks (LITTLE and big)
1219 static const char *armclk_parents[] = {"lpll", "bpll", "dpll", "gpll"};
1221 static struct rk_clk_armclk_rates rk3399_armclkl_rates[] = {
1284 static struct rk_clk_armclk_def armclk_l = {
1288 .parent_names = armclk_parents,
1289 .parent_cnt = nitems(armclk_parents),
1291 /* CRU_CLKSEL_CON0 */
1292 .muxdiv_offset = 0x100,
1299 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1303 .rates = rk3399_armclkl_rates,
1304 .nrates = nitems(rk3399_armclkl_rates),
1307 static struct rk_clk_armclk_rates rk3399_armclkb_rates[] = {
1398 static struct rk_clk_armclk_def armclk_b = {
1402 .parent_names = armclk_parents,
1403 .parent_cnt = nitems(armclk_parents),
1405 .muxdiv_offset = 0x108,
1412 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1416 .rates = rk3399_armclkb_rates,
1417 .nrates = nitems(rk3399_armclkb_rates),
1426 static const char *hclk_sd_parents[] = {"cpll", "gpll"};
1428 static struct rk_clk_composite_def hclk_sd = {
1432 .parent_names = hclk_sd_parents,
1433 .parent_cnt = nitems(hclk_sd_parents),
1436 .muxdiv_offset = 0x134,
1443 .gate_offset = 0x330,
1446 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1449 #define SCLK_SDMMC 76
1451 static const char *sclk_sdmmc_parents[] = {"cpll", "gpll", "npll", "ppll"};
1453 static struct rk_clk_composite_def sclk_sdmmc = {
1456 .name = "sclk_sdmmc",
1457 .parent_names = sclk_sdmmc_parents,
1458 .parent_cnt = nitems(sclk_sdmmc_parents),
1461 .muxdiv_offset = 0x140,
1468 .gate_offset = 0x318,
1471 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1478 #define SCLK_EMMC 78
1480 static const char *sclk_emmc_parents[] = {"cpll", "gpll", "npll"};
1482 static struct rk_clk_composite_def sclk_emmc = {
1485 .name = "sclk_emmc",
1486 .parent_names = sclk_emmc_parents,
1487 .parent_cnt = nitems(sclk_emmc_parents),
1490 .muxdiv_offset = 0x158,
1497 .gate_offset = 0x318,
1500 .flags = RK_CLK_COMPOSITE_HAVE_MUX | RK_CLK_COMPOSITE_HAVE_GATE,
1503 #define ACLK_EMMC 240
1505 static const char *aclk_emmc_parents[] = {
1506 "cpll_aclk_emmc_src",
1507 "gpll_aclk_emmc_src"
1510 static struct rk_clk_composite_def aclk_emmc = {
1513 .name = "aclk_emmc",
1514 .parent_names = aclk_emmc_parents,
1515 .parent_cnt = nitems(aclk_emmc_parents),
1518 .muxdiv_offset = 0x154,
1525 .flags = RK_CLK_COMPOSITE_HAVE_MUX,
1528 static struct rk_clk rk3399_clks[] = {
1530 .type = RK3399_CLK_PLL,
1534 .type = RK3399_CLK_PLL,
1538 .type = RK3399_CLK_PLL,
1542 .type = RK3399_CLK_PLL,
1546 .type = RK3399_CLK_PLL,
1550 .type = RK3399_CLK_PLL,
1554 .type = RK3399_CLK_PLL,
1559 .type = RK_CLK_COMPOSITE,
1560 .clk.composite = &aclk_perihp,
1563 .type = RK_CLK_COMPOSITE,
1564 .clk.composite = &hclk_perihp,
1567 .type = RK_CLK_COMPOSITE,
1568 .clk.composite = &pclk_perihp,
1571 .type = RK_CLK_COMPOSITE,
1572 .clk.composite = &aclk_perilp0,
1575 .type = RK_CLK_COMPOSITE,
1576 .clk.composite = &hclk_perilp0,
1579 .type = RK_CLK_COMPOSITE,
1580 .clk.composite = &pclk_perilp0,
1583 .type = RK_CLK_COMPOSITE,
1584 .clk.composite = &pclk_alive,
1587 .type = RK_CLK_COMPOSITE,
1588 .clk.composite = &hclk_perilp1,
1591 .type = RK_CLK_COMPOSITE,
1592 .clk.composite = &pclk_perilp1,
1595 .type = RK_CLK_COMPOSITE,
1596 .clk.composite = &i2c1,
1599 .type = RK_CLK_COMPOSITE,
1600 .clk.composite = &i2c2,
1603 .type = RK_CLK_COMPOSITE,
1604 .clk.composite = &i2c3,
1607 .type = RK_CLK_COMPOSITE,
1608 .clk.composite = &i2c5,
1611 .type = RK_CLK_COMPOSITE,
1612 .clk.composite = &i2c6,
1615 .type = RK_CLK_COMPOSITE,
1616 .clk.composite = &i2c7,
1620 .type = RK_CLK_ARMCLK,
1621 .clk.armclk = &armclk_l,
1624 .type = RK_CLK_ARMCLK,
1625 .clk.armclk = &armclk_b,
1629 .type = RK_CLK_COMPOSITE,
1630 .clk.composite = &hclk_sd,
1633 .type = RK_CLK_COMPOSITE,
1634 .clk.composite = &sclk_sdmmc,
1638 .type = RK_CLK_COMPOSITE,
1639 .clk.composite = &sclk_emmc,
1642 .type = RK_CLK_COMPOSITE,
1643 .clk.composite = &aclk_emmc,
1648 rk3399_cru_probe(device_t dev)
1651 if (!ofw_bus_status_okay(dev))
1654 if (ofw_bus_is_compatible(dev, "rockchip,rk3399-cru")) {
1655 device_set_desc(dev, "Rockchip RK3399 Clock and Reset Unit");
1656 return (BUS_PROBE_DEFAULT);
1663 rk3399_cru_attach(device_t dev)
1665 struct rk_cru_softc *sc;
1667 sc = device_get_softc(dev);
1670 sc->gates = rk3399_gates;
1671 sc->ngates = nitems(rk3399_gates);
1673 sc->clks = rk3399_clks;
1674 sc->nclks = nitems(rk3399_clks);
1676 sc->reset_offset = 0x400;
1677 sc->reset_num = 335;
1679 return (rk_cru_attach(dev));
1682 static device_method_t rk3399_cru_methods[] = {
1683 /* Device interface */
1684 DEVMETHOD(device_probe, rk3399_cru_probe),
1685 DEVMETHOD(device_attach, rk3399_cru_attach),
1690 static devclass_t rk3399_cru_devclass;
1692 DEFINE_CLASS_1(rk3399_cru, rk3399_cru_driver, rk3399_cru_methods,
1693 sizeof(struct rk_cru_softc), rk_cru_driver);
1695 EARLY_DRIVER_MODULE(rk3399_cru, simplebus, rk3399_cru_driver,
1696 rk3399_cru_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);