1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2019 Emmanuel Vadot <manu@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/param.h> 29 #include <sys/systm.h> 30 #include <sys/bus.h> 31 #include <sys/rman.h> 32 #include <sys/kernel.h> 33 #include <sys/module.h> 34 #include <machine/bus.h> 35 36 #include <dev/fdt/simplebus.h> 37 38 #include <dev/ofw/ofw_bus.h> 39 #include <dev/ofw/ofw_bus_subr.h> 40 41 #include <dev/clk/clk_div.h> 42 #include <dev/clk/clk_fixed.h> 43 #include <dev/clk/clk_mux.h> 44 45 #include <dev/clk/allwinner/aw_ccung.h> 46 47 #include <dt-bindings/clock/sun50i-h6-ccu.h> 48 #include <dt-bindings/reset/sun50i-h6-ccu.h> 49 50 /* Non-exported clocks */ 51 #define CLK_OSC_12M 0 52 #define CLK_PLL_CPUX 1 53 #define CLK_PLL_DDR0 2 54 #define CLK_PLL_PERIPH0_2X 4 55 #define CLK_PLL_PERIPH0_4X 5 56 #define CLK_PLL_PERIPH1 6 57 #define CLK_PLL_PERIPH1_2X 7 58 #define CLK_PLL_PERIPH1_4X 8 59 #define CLK_PLL_GPU 9 60 #define CLK_PLL_VIDEO0 10 61 #define CLK_PLL_VIDEO0_4X 11 62 #define CLK_PLL_VIDEO1 12 63 #define CLK_PLL_VIDEO1_4X 13 64 #define CLK_PLL_VE 14 65 #define CLK_PLL_DE 14 66 #define CLK_PLL_HSIC 16 67 68 #define CLK_PSI_AHB1_AHB2 24 69 #define CLK_AHB3 25 70 #define CLK_APB2 27 71 72 static struct aw_ccung_reset h6_ccu_resets[] = { 73 /* PSI_BGR_REG */ 74 CCU_RESET(RST_BUS_PSI, 0x79c, 16) 75 76 /* SMHC_BGR_REG */ 77 CCU_RESET(RST_BUS_MMC0, 0x84c, 16) 78 CCU_RESET(RST_BUS_MMC1, 0x84c, 17) 79 CCU_RESET(RST_BUS_MMC2, 0x84c, 18) 80 81 /* UART_BGR_REG */ 82 CCU_RESET(RST_BUS_UART0, 0x90c, 16) 83 CCU_RESET(RST_BUS_UART1, 0x90c, 17) 84 CCU_RESET(RST_BUS_UART2, 0x90c, 18) 85 CCU_RESET(RST_BUS_UART3, 0x90c, 19) 86 87 /* TWI_BGR_REG */ 88 CCU_RESET(RST_BUS_I2C0, 0x91c, 16) 89 CCU_RESET(RST_BUS_I2C1, 0x91c, 17) 90 CCU_RESET(RST_BUS_I2C2, 0x91c, 18) 91 CCU_RESET(RST_BUS_I2C3, 0x91c, 19) 92 93 /* EMAC_BGR_REG */ 94 CCU_RESET(RST_BUS_EMAC, 0x97c, 16) 95 96 /* USB0_CLK_REG */ 97 CCU_RESET(RST_USB_PHY0, 0xa70, 30) 98 99 /* USB1_CLK_REG */ 100 CCU_RESET(RST_USB_PHY1, 0xa74, 30) 101 102 /* USB3_CLK_REG */ 103 CCU_RESET(RST_USB_HSIC, 0xa7c, 28) 104 CCU_RESET(RST_USB_PHY3, 0xa7c, 30) 105 106 /* USB_BGR_REG */ 107 CCU_RESET(RST_BUS_OHCI0, 0xa8c, 16) 108 CCU_RESET(RST_BUS_OHCI3, 0xa8c, 19) 109 CCU_RESET(RST_BUS_EHCI0, 0xa8c, 20) 110 CCU_RESET(RST_BUS_XHCI, 0xa8c, 21) 111 CCU_RESET(RST_BUS_EHCI3, 0xa8c, 23) 112 CCU_RESET(RST_BUS_OTG, 0xa8c, 24) 113 }; 114 115 static struct aw_ccung_gate h6_ccu_gates[] = { 116 /* PSI_BGR_REG */ 117 CCU_GATE(CLK_BUS_PSI, "bus-psi", "psi_ahb1_ahb2", 0x79c, 0) 118 119 /* SMHC_BGR_REG */ 120 CCU_GATE(CLK_BUS_MMC0, "bus-mmc0", "ahb3", 0x84c, 0) 121 CCU_GATE(CLK_BUS_MMC1, "bus-mmc1", "ahb3", 0x84c, 1) 122 CCU_GATE(CLK_BUS_MMC2, "bus-mmc2", "ahb3", 0x84c, 2) 123 124 /* UART_BGR_REG Enabling the gate enable weir behavior ... */ 125 /* CCU_GATE(CLK_BUS_UART0, "bus-uart0", "apb2", 0x90c, 0) */ 126 /* CCU_GATE(CLK_BUS_UART1, "bus-uart1", "apb2", 0x90c, 1) */ 127 /* CCU_GATE(CLK_BUS_UART2, "bus-uart2", "apb2", 0x90c, 2) */ 128 /* CCU_GATE(CLK_BUS_UART3, "bus-uart3", "apb2", 0x90c, 3) */ 129 130 /* TWI_BGR_REG */ 131 CCU_GATE(CLK_BUS_I2C0, "bus-i2c0", "apb2", 0x91c, 0) 132 CCU_GATE(CLK_BUS_I2C1, "bus-i2c1", "apb2", 0x91c, 1) 133 CCU_GATE(CLK_BUS_I2C2, "bus-i2c2", "apb2", 0x91c, 2) 134 CCU_GATE(CLK_BUS_I2C3, "bus-i2c3", "apb2", 0x91c, 3) 135 136 /* EMAC_BGR_REG */ 137 CCU_GATE(CLK_BUS_EMAC, "bus-emac", "ahb3", 0x97c, 0) 138 139 /* USB0_CLK_REG */ 140 CCU_GATE(CLK_USB_PHY0, "usb-phy0", "ahb3", 0xa70, 29) 141 CCU_GATE(CLK_USB_OHCI0, "usb-ohci0", "ahb3", 0xa70, 31) 142 143 /* USB1_CLK_REG */ 144 CCU_GATE(CLK_USB_PHY1, "usb-phy1", "ahb3", 0xa74, 29) 145 146 /* USB3_CLK_REG */ 147 CCU_GATE(CLK_USB_HSIC, "usb-hsic", "ahb3", 0xa7c, 26) 148 CCU_GATE(CLK_USB_HSIC_12M, "usb-hsic-12M", "ahb3", 0xa7c, 27) 149 CCU_GATE(CLK_USB_PHY3, "usb-phy3", "ahb3", 0xa7c, 29) 150 CCU_GATE(CLK_USB_OHCI3, "usb-ohci3", "ahb3", 0xa7c, 31) 151 152 /* USB_BGR_REG */ 153 CCU_GATE(CLK_BUS_OHCI0, "bus-ohci0", "ahb3", 0xa8c, 0) 154 CCU_GATE(CLK_BUS_OHCI3, "bus-ohci3", "ahb3", 0xa8c, 3) 155 CCU_GATE(CLK_BUS_EHCI0, "bus-ehci0", "ahb3", 0xa8c, 4) 156 CCU_GATE(CLK_BUS_XHCI, "bus-xhci", "ahb3", 0xa8c, 5) 157 CCU_GATE(CLK_BUS_EHCI3, "bus-ehci3", "ahb3", 0xa8c, 7) 158 CCU_GATE(CLK_BUS_OTG, "bus-otg", "ahb3", 0xa8c, 8) 159 }; 160 161 static const char *osc12m_parents[] = {"osc24M"}; 162 FIXED_CLK(osc12m_clk, 163 CLK_OSC_12M, /* id */ 164 "osc12M", /* name */ 165 osc12m_parents, /* parent */ 166 0, /* freq */ 167 1, /* mult */ 168 2, /* div */ 169 0); /* flags */ 170 171 static const char *pll_cpux_parents[] = {"osc24M"}; 172 NP_CLK(pll_cpux_clk, 173 CLK_PLL_CPUX, /* id */ 174 "pll_cpux", pll_cpux_parents, /* name, parents */ 175 0x00, /* offset */ 176 8, 7, 0, 0, /* n factor */ 177 0, 2, 0, 0, /* p factor */ 178 31, /* gate */ 179 28, 1000, /* lock */ 180 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 181 182 static const char *pll_ddr0_parents[] = {"osc24M"}; 183 NMM_CLK(pll_ddr0_clk, 184 CLK_PLL_DDR0, /* id */ 185 "pll_ddr0", pll_ddr0_parents, /* name, parents */ 186 0x10, /* offset */ 187 8, 7, 0, 0, /* n factor */ 188 0, 1, 0, 0, /* m0 factor */ 189 1, 1, 0, 0, /* m1 factor */ 190 31, /* gate */ 191 28, 1000, /* lock */ 192 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 193 194 static const char *pll_peri0_4x_parents[] = {"osc24M"}; 195 NMM_CLK(pll_peri0_4x_clk, 196 CLK_PLL_PERIPH0_4X, /* id */ 197 "pll_periph0_4x", pll_peri0_4x_parents, /* name, parents */ 198 0x20, /* offset */ 199 8, 7, 0, 0, /* n factor */ 200 0, 1, 0, 0, /* m0 factor */ 201 1, 1, 0, 0, /* m1 factor */ 202 31, /* gate */ 203 28, 1000, /* lock */ 204 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 205 static const char *pll_peri0_2x_parents[] = {"pll_periph0_4x"}; 206 FIXED_CLK(pll_peri0_2x_clk, 207 CLK_PLL_PERIPH0_2X, /* id */ 208 "pll_periph0_2x", /* name */ 209 pll_peri0_2x_parents, /* parent */ 210 0, /* freq */ 211 1, /* mult */ 212 2, /* div */ 213 0); /* flags */ 214 static const char *pll_peri0_parents[] = {"pll_periph0_4x"}; 215 FIXED_CLK(pll_peri0_clk, 216 CLK_PLL_PERIPH0, /* id */ 217 "pll_periph0", /* name */ 218 pll_peri0_parents, /* parent */ 219 0, /* freq */ 220 1, /* mult */ 221 4, /* div */ 222 0); /* flags */ 223 224 static const char *pll_peri1_4x_parents[] = {"osc24M"}; 225 NMM_CLK(pll_peri1_4x_clk, 226 CLK_PLL_PERIPH1_4X, /* id */ 227 "pll_periph1_4x", pll_peri1_4x_parents, /* name, parents */ 228 0x28, /* offset */ 229 8, 7, 0, 0, /* n factor */ 230 0, 1, 0, 0, /* m0 factor */ 231 1, 1, 0, 0, /* m1 factor */ 232 31, /* gate */ 233 28, 1000, /* lock */ 234 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 235 static const char *pll_peri1_2x_parents[] = {"pll_periph1_4x"}; 236 FIXED_CLK(pll_peri1_2x_clk, 237 CLK_PLL_PERIPH1_2X, /* id */ 238 "pll_periph1_2x", /* name */ 239 pll_peri1_2x_parents, /* parent */ 240 0, /* freq */ 241 1, /* mult */ 242 2, /* div */ 243 0); /* flags */ 244 static const char *pll_peri1_parents[] = {"pll_periph1_4x"}; 245 FIXED_CLK(pll_peri1_clk, 246 CLK_PLL_PERIPH1, /* id */ 247 "pll_periph1", /* name */ 248 pll_peri1_parents, /* parent */ 249 0, /* freq */ 250 1, /* mult */ 251 4, /* div */ 252 0); /* flags */ 253 254 static const char *pll_gpu_parents[] = {"osc24M"}; 255 NMM_CLK(pll_gpu_clk, 256 CLK_PLL_GPU, /* id */ 257 "pll_gpu", pll_gpu_parents, /* name, parents */ 258 0x30, /* offset */ 259 8, 7, 0, 0, /* n factor */ 260 0, 1, 0, 0, /* m0 factor */ 261 1, 1, 0, 0, /* m1 factor */ 262 31, /* gate */ 263 28, 1000, /* lock */ 264 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 265 266 static const char *pll_video0_4x_parents[] = {"osc24M"}; 267 NMM_CLK(pll_video0_4x_clk, 268 CLK_PLL_VIDEO0_4X, /* id */ 269 "pll_video0_4x", pll_video0_4x_parents, /* name, parents */ 270 0x40, /* offset */ 271 8, 7, 0, 0, /* n factor */ 272 0, 1, 0, 0, /* m0 factor */ 273 1, 1, 0, 0, /* m1 factor */ 274 31, /* gate */ 275 28, 1000, /* lock */ 276 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 277 static const char *pll_video0_parents[] = {"pll_video0_4x"}; 278 FIXED_CLK(pll_video0_clk, 279 CLK_PLL_VIDEO0, /* id */ 280 "pll_video0", /* name */ 281 pll_video0_parents, /* parent */ 282 0, /* freq */ 283 1, /* mult */ 284 4, /* div */ 285 0); /* flags */ 286 287 static const char *pll_video1_4x_parents[] = {"osc24M"}; 288 NMM_CLK(pll_video1_4x_clk, 289 CLK_PLL_VIDEO1_4X, /* id */ 290 "pll_video1_4x", pll_video1_4x_parents, /* name, parents */ 291 0x48, /* offset */ 292 8, 7, 0, 0, /* n factor */ 293 0, 1, 0, 0, /* m0 factor */ 294 1, 1, 0, 0, /* m1 factor */ 295 31, /* gate */ 296 28, 1000, /* lock */ 297 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 298 static const char *pll_video1_parents[] = {"pll_video1_4x"}; 299 FIXED_CLK(pll_video1_clk, 300 CLK_PLL_VIDEO1, /* id */ 301 "pll_video1", /* name */ 302 pll_video1_parents, /* parent */ 303 0, /* freq */ 304 1, /* mult */ 305 4, /* div */ 306 0); /* flags */ 307 308 static const char *pll_ve_parents[] = {"osc24M"}; 309 NMM_CLK(pll_ve_clk, 310 CLK_PLL_VE, /* id */ 311 "pll_ve", pll_ve_parents, /* name, parents */ 312 0x58, /* offset */ 313 8, 7, 0, 0, /* n factor */ 314 0, 1, 0, 0, /* m0 factor */ 315 1, 1, 0, 0, /* m1 factor */ 316 31, /* gate */ 317 28, 1000, /* lock */ 318 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 319 320 static const char *pll_de_parents[] = {"osc24M"}; 321 NMM_CLK(pll_de_clk, 322 CLK_PLL_DE, /* id */ 323 "pll_de", pll_de_parents, /* name, parents */ 324 0x60, /* offset */ 325 8, 7, 0, 0, /* n factor */ 326 0, 1, 0, 0, /* m0 factor */ 327 1, 1, 0, 0, /* m1 factor */ 328 31, /* gate */ 329 28, 1000, /* lock */ 330 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 331 332 static const char *pll_hsic_parents[] = {"osc24M"}; 333 NMM_CLK(pll_hsic_clk, 334 CLK_PLL_HSIC, /* id */ 335 "pll_hsic", pll_hsic_parents, /* name, parents */ 336 0x70, /* offset */ 337 8, 7, 0, 0, /* n factor */ 338 0, 1, 0, 0, /* m0 factor */ 339 1, 1, 0, 0, /* m1 factor */ 340 31, /* gate */ 341 28, 1000, /* lock */ 342 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 343 344 /* PLL_AUDIO missing */ 345 346 /* CPUX_AXI missing */ 347 348 static const char *psi_ahb1_ahb2_parents[] = {"osc24M", "osc32k", "iosc", "pll_periph0"}; 349 NM_CLK(psi_ahb1_ahb2_clk, 350 CLK_PSI_AHB1_AHB2, "psi_ahb1_ahb2", psi_ahb1_ahb2_parents, /* id, name, parents */ 351 0x510, /* offset */ 352 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 353 0, 2, 0, 0, /* m factor */ 354 24, 2, /* mux */ 355 0, /* gate */ 356 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 357 358 static const char *ahb3_parents[] = {"osc24M", "osc32k", "psi_ahb1_ahb2", "pll_periph0"}; 359 NM_CLK(ahb3_clk, 360 CLK_AHB3, "ahb3", ahb3_parents, /* id, name, parents */ 361 0x51C, /* offset */ 362 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 363 0, 2, 0, 0, /* m factor */ 364 24, 2, /* mux */ 365 0, /* gate */ 366 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 367 368 static const char *apb1_parents[] = {"osc24M", "osc32k", "psi_ahb1_ahb2", "pll_periph0"}; 369 NM_CLK(apb1_clk, 370 CLK_APB1, "apb1", apb1_parents, /* id, name, parents */ 371 0x520, /* offset */ 372 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 373 0, 2, 0, 0, /* m factor */ 374 24, 2, /* mux */ 375 0, /* gate */ 376 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 377 378 static const char *apb2_parents[] = {"osc24M", "osc32k", "psi_ahb1_ahb2", "pll_periph0"}; 379 NM_CLK(apb2_clk, 380 CLK_APB2, "apb2", apb2_parents, /* id, name, parents */ 381 0x524, /* offset */ 382 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 383 0, 2, 0, 0, /* m factor */ 384 24, 2, /* mux */ 385 0, /* gate */ 386 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 387 388 /* Missing MBUS clock */ 389 390 static const char *mod_parents[] = {"osc24M", "pll_periph0_2x", "pll_periph1_2x"}; 391 NM_CLK(mmc0_clk, 392 CLK_MMC0, "mmc0", mod_parents, /* id, name, parents */ 393 0x830, /* offset */ 394 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 395 0, 4, 0, 0, /* m factor */ 396 24, 2, /* mux */ 397 31, /* gate */ 398 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 399 AW_CLK_REPARENT); /* flags */ 400 401 NM_CLK(mmc1_clk, 402 CLK_MMC1, "mmc1", mod_parents, /* id, name, parents */ 403 0x834, /* offset */ 404 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 405 0, 4, 0, 0, /* m factor */ 406 24, 2, /* mux */ 407 31, /* gate */ 408 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 409 AW_CLK_REPARENT); /* flags */ 410 411 NM_CLK(mmc2_clk, 412 CLK_MMC2, "mmc2", mod_parents, /* id, name, parents */ 413 0x838, /* offset */ 414 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 415 0, 4, 0, 0, /* m factor */ 416 24, 2, /* mux */ 417 31, /* gate */ 418 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 419 AW_CLK_REPARENT); /* flags */ 420 421 static struct aw_ccung_clk h6_ccu_clks[] = { 422 { .type = AW_CLK_NP, .clk.np = &pll_cpux_clk}, 423 { .type = AW_CLK_NMM, .clk.nmm = &pll_ddr0_clk}, 424 { .type = AW_CLK_NMM, .clk.nmm = &pll_peri0_4x_clk}, 425 { .type = AW_CLK_NMM, .clk.nmm = &pll_peri1_4x_clk}, 426 { .type = AW_CLK_NMM, .clk.nmm = &pll_gpu_clk}, 427 { .type = AW_CLK_NMM, .clk.nmm = &pll_video0_4x_clk}, 428 { .type = AW_CLK_NMM, .clk.nmm = &pll_video1_4x_clk}, 429 { .type = AW_CLK_NMM, .clk.nmm = &pll_ve_clk}, 430 { .type = AW_CLK_NMM, .clk.nmm = &pll_de_clk}, 431 { .type = AW_CLK_NMM, .clk.nmm = &pll_hsic_clk}, 432 433 { .type = AW_CLK_NM, .clk.nm = &psi_ahb1_ahb2_clk}, 434 { .type = AW_CLK_NM, .clk.nm = &ahb3_clk}, 435 { .type = AW_CLK_NM, .clk.nm = &apb1_clk}, 436 { .type = AW_CLK_NM, .clk.nm = &apb2_clk}, 437 438 { .type = AW_CLK_NM, .clk.nm = &mmc0_clk}, 439 { .type = AW_CLK_NM, .clk.nm = &mmc1_clk}, 440 { .type = AW_CLK_NM, .clk.nm = &mmc2_clk}, 441 442 { .type = AW_CLK_FIXED, .clk.fixed = &osc12m_clk}, 443 { .type = AW_CLK_FIXED, .clk.fixed = &pll_peri0_2x_clk}, 444 { .type = AW_CLK_FIXED, .clk.fixed = &pll_peri0_clk}, 445 { .type = AW_CLK_FIXED, .clk.fixed = &pll_peri1_2x_clk}, 446 { .type = AW_CLK_FIXED, .clk.fixed = &pll_peri1_clk}, 447 { .type = AW_CLK_FIXED, .clk.fixed = &pll_video0_clk}, 448 { .type = AW_CLK_FIXED, .clk.fixed = &pll_video1_clk}, 449 }; 450 451 static int 452 ccu_h6_probe(device_t dev) 453 { 454 455 if (!ofw_bus_status_okay(dev)) 456 return (ENXIO); 457 458 if (!ofw_bus_is_compatible(dev, "allwinner,sun50i-h6-ccu")) 459 return (ENXIO); 460 461 device_set_desc(dev, "Allwinner H6 Clock Control Unit NG"); 462 return (BUS_PROBE_DEFAULT); 463 } 464 465 static int 466 ccu_h6_attach(device_t dev) 467 { 468 struct aw_ccung_softc *sc; 469 470 sc = device_get_softc(dev); 471 472 sc->resets = h6_ccu_resets; 473 sc->nresets = nitems(h6_ccu_resets); 474 sc->gates = h6_ccu_gates; 475 sc->ngates = nitems(h6_ccu_gates); 476 sc->clks = h6_ccu_clks; 477 sc->nclks = nitems(h6_ccu_clks); 478 479 return (aw_ccung_attach(dev)); 480 } 481 482 static device_method_t ccu_h6ng_methods[] = { 483 /* Device interface */ 484 DEVMETHOD(device_probe, ccu_h6_probe), 485 DEVMETHOD(device_attach, ccu_h6_attach), 486 487 DEVMETHOD_END 488 }; 489 490 DEFINE_CLASS_1(ccu_h6ng, ccu_h6ng_driver, ccu_h6ng_methods, 491 sizeof(struct aw_ccung_softc), aw_ccung_driver); 492 493 EARLY_DRIVER_MODULE(ccu_h6ng, simplebus, ccu_h6ng_driver, 0, 0, 494 BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); 495