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