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