1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2017,2018 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/sun5i-ccu.h> 48 #include <dt-bindings/reset/sun5i-ccu.h> 49 50 /* Non-exported clocks */ 51 52 #define CLK_PLL_CORE 2 53 #define CLK_PLL_AUDIO_BASE 3 54 #define CLK_PLL_AUDIO 4 55 #define CLK_PLL_AUDIO_2X 5 56 #define CLK_PLL_AUDIO_4X 6 57 #define CLK_PLL_AUDIO_8X 7 58 #define CLK_PLL_VIDEO0 8 59 60 #define CLK_PLL_VE 10 61 #define CLK_PLL_DDR_BASE 11 62 #define CLK_PLL_DDR 12 63 #define CLK_PLL_DDR_OTHER 13 64 #define CLK_PLL_PERIPH 14 65 #define CLK_PLL_VIDEO1 15 66 67 #define CLK_AXI 18 68 #define CLK_AHB 19 69 #define CLK_APB0 20 70 #define CLK_APB1 21 71 #define CLK_DRAM_AXI 22 72 73 #define CLK_TCON_CH1_SCLK 91 74 75 #define CLK_MBUS 99 76 77 static struct aw_ccung_reset a13_ccu_resets[] = { 78 CCU_RESET(RST_USB_PHY0, 0xcc, 0) 79 CCU_RESET(RST_USB_PHY1, 0xcc, 1) 80 81 CCU_RESET(RST_GPS, 0xd0, 30) 82 83 CCU_RESET(RST_DE_BE, 0x104, 30) 84 85 CCU_RESET(RST_DE_FE, 0x10c, 30) 86 87 CCU_RESET(RST_TVE, 0x118, 29) 88 CCU_RESET(RST_LCD, 0x118, 30) 89 90 CCU_RESET(RST_CSI, 0x134, 30) 91 92 CCU_RESET(RST_VE, 0x13c, 0) 93 CCU_RESET(RST_GPU, 0x154, 30) 94 CCU_RESET(RST_IEP, 0x160, 30) 95 96 }; 97 98 static struct aw_ccung_gate a13_ccu_gates[] = { 99 CCU_GATE(CLK_HOSC, "hosc", "osc24M", 0x50, 0) 100 101 CCU_GATE(CLK_DRAM_AXI, "axi-dram", "axi", 0x5c, 0) 102 103 CCU_GATE(CLK_AHB_OTG, "ahb-otg", "ahb", 0x60, 0) 104 CCU_GATE(CLK_AHB_EHCI, "ahb-ehci", "ahb", 0x60, 1) 105 CCU_GATE(CLK_AHB_OHCI, "ahb-ohci", "ahb", 0x60, 2) 106 CCU_GATE(CLK_AHB_SS, "ahb-ss", "ahb", 0x60, 5) 107 CCU_GATE(CLK_AHB_DMA, "ahb-dma", "ahb", 0x60, 6) 108 CCU_GATE(CLK_AHB_BIST, "ahb-bist", "ahb", 0x60, 7) 109 CCU_GATE(CLK_AHB_MMC0, "ahb-mmc0", "ahb", 0x60, 8) 110 CCU_GATE(CLK_AHB_MMC1, "ahb-mmc1", "ahb", 0x60, 9) 111 CCU_GATE(CLK_AHB_MMC2, "ahb-mmc2", "ahb", 0x60, 10) 112 CCU_GATE(CLK_AHB_NAND, "ahb-nand", "ahb", 0x60, 13) 113 CCU_GATE(CLK_AHB_SDRAM, "ahb-sdram", "ahb", 0x60, 14) 114 CCU_GATE(CLK_AHB_SPI0, "ahb-spi0", "ahb", 0x60, 20) 115 CCU_GATE(CLK_AHB_SPI1, "ahb-spi1", "ahb", 0x60, 21) 116 CCU_GATE(CLK_AHB_SPI2, "ahb-spi2", "ahb", 0x60, 22) 117 CCU_GATE(CLK_AHB_GPS, "ahb-gps", "ahb", 0x60, 26) 118 CCU_GATE(CLK_AHB_HSTIMER, "ahb-hstimer", "ahb", 0x60, 28) 119 120 CCU_GATE(CLK_AHB_VE, "ahb-ve", "ahb", 0x64, 0) 121 CCU_GATE(CLK_AHB_LCD, "ahb-lcd", "ahb", 0x64, 4) 122 CCU_GATE(CLK_AHB_CSI, "ahb-csi", "ahb", 0x64, 8) 123 CCU_GATE(CLK_AHB_DE_BE, "ahb-de-be", "ahb", 0x64, 12) 124 CCU_GATE(CLK_AHB_DE_FE, "ahb-de-fe", "ahb", 0x64, 14) 125 CCU_GATE(CLK_AHB_IEP, "ahb-iep", "ahb", 0x64, 19) 126 CCU_GATE(CLK_AHB_GPU, "ahb-gpu", "ahb", 0x64, 20) 127 128 CCU_GATE(CLK_APB0_CODEC, "apb0-codec", "apb0", 0x68, 0) 129 CCU_GATE(CLK_APB0_PIO, "apb0-pio", "apb0", 0x68, 5) 130 CCU_GATE(CLK_APB0_IR, "apb0-ir", "apb0", 0x68, 6) 131 132 CCU_GATE(CLK_APB1_I2C0, "apb1-i2c0", "apb1", 0x6c, 0) 133 CCU_GATE(CLK_APB1_I2C1, "apb1-i2c1", "apb1", 0x6c, 1) 134 CCU_GATE(CLK_APB1_I2C2, "apb1-i2c2", "apb1", 0x6c, 2) 135 CCU_GATE(CLK_APB1_UART1, "apb1-uart1", "apb1", 0x6c, 17) 136 CCU_GATE(CLK_APB1_UART3, "apb1-uart3", "apb1", 0x6c, 19) 137 138 CCU_GATE(CLK_DRAM_VE, "dram-ve", "pll-ddr", 0x100, 0) 139 CCU_GATE(CLK_DRAM_CSI, "dram-csi", "pll-ddr", 0x100, 1) 140 CCU_GATE(CLK_DRAM_DE_FE, "dram-de-fe", "pll-ddr", 0x100, 25) 141 CCU_GATE(CLK_DRAM_DE_BE, "dram-de-be", "pll-ddr", 0x100, 26) 142 CCU_GATE(CLK_DRAM_ACE, "dram-ace", "pll-ddr", 0x100, 29) 143 CCU_GATE(CLK_DRAM_IEP, "dram-iep", "pll-ddr", 0x100, 31) 144 145 CCU_GATE(CLK_CODEC, "codec", "pll-audio", 0x140, 31) 146 147 CCU_GATE(CLK_AVS, "avs", "hosc", 0x144, 31) 148 }; 149 150 static const char *pll_parents[] = {"hosc"}; 151 static struct aw_clk_nkmp_def pll_core = { 152 .clkdef = { 153 .id = CLK_PLL_CORE, 154 .name = "pll-core", 155 .parent_names = pll_parents, 156 .parent_cnt = nitems(pll_parents), 157 }, 158 .offset = 0x00, 159 .n = {.shift = 8, .width = 5}, 160 .k = {.shift = 4, .width = 2}, 161 .m = {.shift = 0, .width = 2}, 162 .p = {.shift = 16, .width = 2}, 163 .gate_shift = 31, 164 .flags = AW_CLK_HAS_GATE, 165 }; 166 167 /* 168 * We only implement pll-audio for now 169 * For pll-audio-2/4/8 x we need a way to change the frequency 170 * of the parent clocks 171 */ 172 static struct aw_clk_nkmp_def pll_audio = { 173 .clkdef = { 174 .id = CLK_PLL_AUDIO, 175 .name = "pll-audio", 176 .parent_names = pll_parents, 177 .parent_cnt = nitems(pll_parents), 178 }, 179 .offset = 0x08, 180 .n = {.shift = 8, .width = 7}, 181 .k = {.value = 1, .flags = AW_CLK_FACTOR_FIXED}, 182 .m = {.shift = 0, .width = 5}, 183 .p = {.shift = 26, .width = 4}, 184 .gate_shift = 31, 185 .flags = AW_CLK_HAS_GATE, 186 }; 187 188 /* Missing PLL3-Video */ 189 /* Missing PLL4-VE */ 190 191 static struct aw_clk_nkmp_def pll_ddr_base = { 192 .clkdef = { 193 .id = CLK_PLL_DDR_BASE, 194 .name = "pll-ddr-base", 195 .parent_names = pll_parents, 196 .parent_cnt = nitems(pll_parents), 197 }, 198 .offset = 0x20, 199 .n = {.shift = 8, .width = 5}, 200 .k = {.shift = 4, .width = 2}, 201 .m = {.value = 1, .flags = AW_CLK_FACTOR_FIXED}, 202 .p = {.value = 1, .flags = AW_CLK_FACTOR_FIXED}, 203 .gate_shift = 31, 204 .flags = AW_CLK_HAS_GATE, 205 }; 206 207 static const char *pll_ddr_parents[] = {"pll-ddr-base"}; 208 static struct clk_div_def pll_ddr = { 209 .clkdef = { 210 .id = CLK_PLL_DDR, 211 .name = "pll-ddr", 212 .parent_names = pll_ddr_parents, 213 .parent_cnt = nitems(pll_ddr_parents), 214 }, 215 .offset = 0x20, 216 .i_shift = 0, 217 .i_width = 2, 218 }; 219 220 static const char *pll_ddr_other_parents[] = {"pll-ddr-base"}; 221 static struct clk_div_def pll_ddr_other = { 222 .clkdef = { 223 .id = CLK_PLL_DDR_OTHER, 224 .name = "pll-ddr-other", 225 .parent_names = pll_ddr_other_parents, 226 .parent_cnt = nitems(pll_ddr_other_parents), 227 }, 228 .offset = 0x20, 229 .i_shift = 16, 230 .i_width = 2, 231 }; 232 233 static struct aw_clk_nkmp_def pll_periph = { 234 .clkdef = { 235 .id = CLK_PLL_PERIPH, 236 .name = "pll-periph", 237 .parent_names = pll_parents, 238 .parent_cnt = nitems(pll_parents), 239 }, 240 .offset = 0x28, 241 .n = {.shift = 8, .width = 5}, 242 .k = {.shift = 4, .width = 2}, 243 .m = {.shift = 0, .width = 2}, 244 .p = {.value = 2, .flags = AW_CLK_FACTOR_FIXED}, 245 .gate_shift = 31, 246 .flags = AW_CLK_HAS_GATE, 247 }; 248 249 /* Missing PLL7-VIDEO1 */ 250 251 static const char *cpu_parents[] = {"osc32k", "hosc", "pll-core", "pll-periph"}; 252 static struct aw_clk_prediv_mux_def cpu_clk = { 253 .clkdef = { 254 .id = CLK_CPU, 255 .name = "cpu", 256 .parent_names = cpu_parents, 257 .parent_cnt = nitems(cpu_parents), 258 }, 259 .offset = 0x54, 260 .mux_shift = 16, .mux_width = 2, 261 .prediv = { 262 .value = 6, 263 .flags = AW_CLK_FACTOR_FIXED, 264 .cond_shift = 16, 265 .cond_width = 2, 266 .cond_value = 3, 267 }, 268 }; 269 270 static const char *axi_parents[] = {"cpu"}; 271 static struct clk_div_def axi_clk = { 272 .clkdef = { 273 .id = CLK_AXI, 274 .name = "axi", 275 .parent_names = axi_parents, 276 .parent_cnt = nitems(axi_parents), 277 }, 278 .offset = 0x50, 279 .i_shift = 0, .i_width = 2, 280 }; 281 282 static const char *ahb_parents[] = {"axi", "cpu", "pll-periph"}; 283 static struct aw_clk_prediv_mux_def ahb_clk = { 284 .clkdef = { 285 .id = CLK_AHB, 286 .name = "ahb", 287 .parent_names = ahb_parents, 288 .parent_cnt = nitems(ahb_parents), 289 }, 290 .offset = 0x54, 291 .mux_shift = 6, 292 .mux_width = 2, 293 .div = { 294 .shift = 4, 295 .width = 2, 296 .flags = AW_CLK_FACTOR_POWER_OF_TWO 297 }, 298 .prediv = { 299 .value = 2, 300 .flags = AW_CLK_FACTOR_FIXED, 301 .cond_shift = 6, 302 .cond_width = 2, 303 .cond_value = 2, 304 }, 305 }; 306 307 static const char *apb0_parents[] = {"ahb"}; 308 static struct clk_div_table apb0_div_table[] = { 309 { .value = 0, .divider = 2, }, 310 { .value = 1, .divider = 2, }, 311 { .value = 2, .divider = 4, }, 312 { .value = 3, .divider = 8, }, 313 { }, 314 }; 315 static struct clk_div_def apb0_clk = { 316 .clkdef = { 317 .id = CLK_APB0, 318 .name = "apb0", 319 .parent_names = apb0_parents, 320 .parent_cnt = nitems(apb0_parents), 321 }, 322 .offset = 0x54, 323 .i_shift = 8, .i_width = 2, 324 .div_flags = CLK_DIV_WITH_TABLE, 325 .div_table = apb0_div_table, 326 }; 327 328 static const char *apb1_parents[] = {"hosc", "pll-periph", "osc32k"}; 329 static struct aw_clk_nm_def apb1_clk = { 330 .clkdef = { 331 .id = CLK_APB1, 332 .name = "apb1", 333 .parent_names = apb1_parents, 334 .parent_cnt = nitems(apb1_parents), 335 }, 336 .offset = 0x58, 337 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 338 .m = {.shift = 0, .width = 5}, 339 .mux_shift = 24, 340 .mux_width = 2, 341 .flags = AW_CLK_HAS_MUX, 342 }; 343 344 static const char *mod_parents[] = {"hosc", "pll-periph", "pll-ddr-other"}; 345 346 static struct aw_clk_nm_def nand_clk = { 347 .clkdef = { 348 .id = CLK_NAND, 349 .name = "nand", 350 .parent_names = mod_parents, 351 .parent_cnt = nitems(mod_parents), 352 }, 353 .offset = 0x80, 354 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 355 .m = {.shift = 0, .width = 4}, 356 .mux_shift = 24, 357 .mux_width = 2, 358 .gate_shift = 31, 359 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 360 }; 361 362 static struct aw_clk_nm_def mmc0_clk = { 363 .clkdef = { 364 .id = CLK_MMC0, 365 .name = "mmc0", 366 .parent_names = mod_parents, 367 .parent_cnt = nitems(mod_parents), 368 }, 369 .offset = 0x88, 370 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 371 .m = {.shift = 0, .width = 4}, 372 .mux_shift = 24, 373 .mux_width = 2, 374 .gate_shift = 31, 375 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 376 }; 377 378 static struct aw_clk_nm_def mmc1_clk = { 379 .clkdef = { 380 .id = CLK_MMC1, 381 .name = "mmc1", 382 .parent_names = mod_parents, 383 .parent_cnt = nitems(mod_parents), 384 }, 385 .offset = 0x8C, 386 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 387 .m = {.shift = 0, .width = 4}, 388 .mux_shift = 24, 389 .mux_width = 2, 390 .gate_shift = 31, 391 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 392 }; 393 394 static struct aw_clk_nm_def mmc2_clk = { 395 .clkdef = { 396 .id = CLK_MMC2, 397 .name = "mmc2", 398 .parent_names = mod_parents, 399 .parent_cnt = nitems(mod_parents), 400 }, 401 .offset = 0x90, 402 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 403 .m = {.shift = 0, .width = 4}, 404 .mux_shift = 24, 405 .mux_width = 2, 406 .gate_shift = 31, 407 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 408 }; 409 410 static struct aw_clk_nm_def ss_clk = { 411 .clkdef = { 412 .id = CLK_SS, 413 .name = "ss", 414 .parent_names = mod_parents, 415 .parent_cnt = nitems(mod_parents), 416 }, 417 .offset = 0x9C, 418 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 419 .m = {.shift = 0, .width = 4}, 420 .mux_shift = 24, 421 .mux_width = 2, 422 .gate_shift = 31, 423 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 424 }; 425 426 static struct aw_clk_nm_def spi0_clk = { 427 .clkdef = { 428 .id = CLK_SPI0, 429 .name = "spi0", 430 .parent_names = mod_parents, 431 .parent_cnt = nitems(mod_parents), 432 }, 433 .offset = 0xA0, 434 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 435 .m = {.shift = 0, .width = 4}, 436 .mux_shift = 24, 437 .mux_width = 2, 438 .gate_shift = 31, 439 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 440 }; 441 442 static struct aw_clk_nm_def spi1_clk = { 443 .clkdef = { 444 .id = CLK_SPI1, 445 .name = "spi1", 446 .parent_names = mod_parents, 447 .parent_cnt = nitems(mod_parents), 448 }, 449 .offset = 0xA4, 450 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 451 .m = {.shift = 0, .width = 4}, 452 .mux_shift = 24, 453 .mux_width = 2, 454 .gate_shift = 31, 455 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 456 }; 457 458 static struct aw_clk_nm_def spi2_clk = { 459 .clkdef = { 460 .id = CLK_SPI2, 461 .name = "spi2", 462 .parent_names = mod_parents, 463 .parent_cnt = nitems(mod_parents), 464 }, 465 .offset = 0xA8, 466 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 467 .m = {.shift = 0, .width = 4}, 468 .mux_shift = 24, 469 .mux_width = 2, 470 .gate_shift = 31, 471 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 472 }; 473 474 static struct aw_clk_nm_def ir_clk = { 475 .clkdef = { 476 .id = CLK_IR, 477 .name = "ir", 478 .parent_names = mod_parents, 479 .parent_cnt = nitems(mod_parents), 480 }, 481 .offset = 0xB0, 482 .n = {.shift = 16, .width = 2, .flags = AW_CLK_FACTOR_POWER_OF_TWO, }, 483 .m = {.shift = 0, .width = 4}, 484 .mux_shift = 24, 485 .mux_width = 2, 486 .gate_shift = 31, 487 .flags = AW_CLK_HAS_MUX | AW_CLK_HAS_GATE | AW_CLK_REPARENT 488 }; 489 490 /* Missing DE-BE clock */ 491 /* Missing DE-FE clock */ 492 /* Missing LCD CH1 clock */ 493 /* Missing CSI clock */ 494 /* Missing VE clock */ 495 496 /* Clocks list */ 497 static struct aw_ccung_clk a13_ccu_clks[] = { 498 { .type = AW_CLK_NKMP, .clk.nkmp = &pll_core}, 499 { .type = AW_CLK_NKMP, .clk.nkmp = &pll_audio}, 500 { .type = AW_CLK_NKMP, .clk.nkmp = &pll_ddr_base}, 501 { .type = AW_CLK_NKMP, .clk.nkmp = &pll_periph}, 502 { .type = AW_CLK_NM, .clk.nm = &apb1_clk}, 503 { .type = AW_CLK_NM, .clk.nm = &nand_clk}, 504 { .type = AW_CLK_NM, .clk.nm = &mmc0_clk}, 505 { .type = AW_CLK_NM, .clk.nm = &mmc1_clk}, 506 { .type = AW_CLK_NM, .clk.nm = &mmc2_clk}, 507 { .type = AW_CLK_NM, .clk.nm = &ss_clk}, 508 { .type = AW_CLK_NM, .clk.nm = &spi0_clk}, 509 { .type = AW_CLK_NM, .clk.nm = &spi1_clk}, 510 { .type = AW_CLK_NM, .clk.nm = &spi2_clk}, 511 { .type = AW_CLK_NM, .clk.nm = &ir_clk}, 512 { .type = AW_CLK_PREDIV_MUX, .clk.prediv_mux = &cpu_clk}, 513 { .type = AW_CLK_PREDIV_MUX, .clk.prediv_mux = &ahb_clk}, 514 { .type = AW_CLK_DIV, .clk.div = &pll_ddr}, 515 { .type = AW_CLK_DIV, .clk.div = &pll_ddr_other}, 516 { .type = AW_CLK_DIV, .clk.div = &axi_clk}, 517 { .type = AW_CLK_DIV, .clk.div = &apb0_clk}, 518 }; 519 520 static int 521 ccu_a13_probe(device_t dev) 522 { 523 524 if (!ofw_bus_status_okay(dev)) 525 return (ENXIO); 526 527 if (!ofw_bus_is_compatible(dev, "allwinner,sun5i-a13-ccu")) 528 return (ENXIO); 529 530 device_set_desc(dev, "Allwinner A13 Clock Control Unit NG"); 531 return (BUS_PROBE_DEFAULT); 532 } 533 534 static int 535 ccu_a13_attach(device_t dev) 536 { 537 struct aw_ccung_softc *sc; 538 539 sc = device_get_softc(dev); 540 541 sc->resets = a13_ccu_resets; 542 sc->nresets = nitems(a13_ccu_resets); 543 sc->gates = a13_ccu_gates; 544 sc->ngates = nitems(a13_ccu_gates); 545 sc->clks = a13_ccu_clks; 546 sc->nclks = nitems(a13_ccu_clks); 547 548 return (aw_ccung_attach(dev)); 549 } 550 551 static device_method_t ccu_a13ng_methods[] = { 552 /* Device interface */ 553 DEVMETHOD(device_probe, ccu_a13_probe), 554 DEVMETHOD(device_attach, ccu_a13_attach), 555 556 DEVMETHOD_END 557 }; 558 559 DEFINE_CLASS_1(ccu_a13ng, ccu_a13ng_driver, ccu_a13ng_methods, 560 sizeof(struct aw_ccung_softc), aw_ccung_driver); 561 562 EARLY_DRIVER_MODULE(ccu_a13ng, simplebus, ccu_a13ng_driver, 0, 0, 563 BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); 564