1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2022 Julien Cassette <julien.cassette@gmail.com> 5 * Copyright (c) 2024 The FreeBSD Foundation 6 * 7 * Portions of this software were developed by Mitchell Horne 8 * <mhorne@FreeBSD.org> under sponsorship from the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/bus.h> 35 #include <sys/rman.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 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/clk/clk_div.h> 47 #include <dev/clk/clk_fixed.h> 48 #include <dev/clk/clk_mux.h> 49 50 #include <dev/clk/allwinner/aw_ccung.h> 51 52 #include <dt-bindings/clock/sun20i-d1-ccu.h> 53 #include <dt-bindings/reset/sun20i-d1-ccu.h> 54 55 static struct aw_ccung_reset ccu_d1_resets[] = { 56 CCU_RESET(RST_MBUS, 0x540, 30) 57 CCU_RESET(RST_BUS_DE, 0x60C, 16) 58 CCU_RESET(RST_BUS_DI, 0x62C, 16) 59 CCU_RESET(RST_BUS_G2D, 0x63C, 16) 60 CCU_RESET(RST_BUS_CE, 0x68C, 16) 61 CCU_RESET(RST_BUS_VE, 0x69C, 16) 62 CCU_RESET(RST_BUS_DMA, 0x70C, 16) 63 CCU_RESET(RST_BUS_MSGBOX0, 0x71C, 16) 64 CCU_RESET(RST_BUS_MSGBOX1, 0x71C, 17) 65 CCU_RESET(RST_BUS_MSGBOX2, 0x71C, 18) 66 CCU_RESET(RST_BUS_SPINLOCK, 0x72C, 16) 67 CCU_RESET(RST_BUS_HSTIMER, 0x73C, 16) 68 CCU_RESET(RST_BUS_DBG, 0x78C, 16) 69 CCU_RESET(RST_BUS_PWM, 0x7AC, 16) 70 CCU_RESET(RST_BUS_DRAM, 0x80C, 16) 71 CCU_RESET(RST_BUS_MMC0, 0x84C, 16) 72 CCU_RESET(RST_BUS_MMC1, 0x84C, 17) 73 CCU_RESET(RST_BUS_MMC2, 0x84C, 18) 74 CCU_RESET(RST_BUS_UART0, 0x90C, 16) 75 CCU_RESET(RST_BUS_UART1, 0x90C, 17) 76 CCU_RESET(RST_BUS_UART2, 0x90C, 18) 77 CCU_RESET(RST_BUS_UART3, 0x90C, 19) 78 CCU_RESET(RST_BUS_UART4, 0x90C, 20) 79 CCU_RESET(RST_BUS_UART5, 0x90C, 21) 80 CCU_RESET(RST_BUS_I2C0, 0x91C, 16) 81 CCU_RESET(RST_BUS_I2C1, 0x91C, 17) 82 CCU_RESET(RST_BUS_I2C2, 0x91C, 18) 83 CCU_RESET(RST_BUS_I2C3, 0x91C, 19) 84 CCU_RESET(RST_BUS_SPI0, 0x96C, 16) 85 CCU_RESET(RST_BUS_SPI1, 0x96C, 17) 86 CCU_RESET(RST_BUS_EMAC, 0x97C, 16) 87 CCU_RESET(RST_BUS_IR_TX, 0x9CC, 16) 88 CCU_RESET(RST_BUS_GPADC, 0x9EC, 16) 89 CCU_RESET(RST_BUS_THS, 0x9FC, 16) 90 CCU_RESET(RST_BUS_I2S0, 0xA20, 16) 91 CCU_RESET(RST_BUS_I2S1, 0xA20, 17) 92 CCU_RESET(RST_BUS_I2S2, 0xA20, 18) 93 CCU_RESET(RST_BUS_SPDIF, 0xA2C, 16) 94 CCU_RESET(RST_BUS_DMIC, 0xA4C, 16) 95 CCU_RESET(RST_BUS_AUDIO, 0xA5C, 16) 96 CCU_RESET(RST_USB_PHY0, 0xA70, 30) 97 CCU_RESET(RST_USB_PHY1, 0xA74, 30) 98 CCU_RESET(RST_BUS_OHCI0, 0xA8C, 16) 99 CCU_RESET(RST_BUS_OHCI1, 0xA8C, 17) 100 CCU_RESET(RST_BUS_EHCI0, 0xA8C, 20) 101 CCU_RESET(RST_BUS_EHCI1, 0xA8C, 21) 102 CCU_RESET(RST_BUS_OTG, 0xA8C, 24) 103 CCU_RESET(RST_BUS_LRADC, 0xA9C, 16) 104 CCU_RESET(RST_BUS_DPSS_TOP, 0xABC, 16) 105 CCU_RESET(RST_BUS_MIPI_DSI, 0xB4C, 16) 106 CCU_RESET(RST_BUS_TCON_LCD0, 0xB7C, 16) 107 CCU_RESET(RST_BUS_TCON_TV, 0xB9C, 16) 108 CCU_RESET(RST_BUS_LVDS0, 0xBAC, 16) 109 CCU_RESET(RST_BUS_TVE, 0xBBC, 17) 110 CCU_RESET(RST_BUS_TVE_TOP, 0xBBC, 16) 111 CCU_RESET(RST_BUS_TVD, 0xBDC, 17) 112 CCU_RESET(RST_BUS_TVD_TOP, 0xBDC, 16) 113 CCU_RESET(RST_BUS_LEDC, 0xBFC, 16) 114 CCU_RESET(RST_BUS_CSI, 0xC1C, 16) 115 CCU_RESET(RST_BUS_TPADC, 0xC5C, 16) 116 CCU_RESET(RST_DSP, 0xC7C, 16) 117 CCU_RESET(RST_BUS_DSP_CFG, 0xC7C, 17) 118 CCU_RESET(RST_BUS_DSP_DBG, 0xC7C, 18) 119 CCU_RESET(RST_BUS_RISCV_CFG, 0xD0C, 16) 120 CCU_RESET(RST_BUS_CAN0, 0x92C, 16) 121 CCU_RESET(RST_BUS_CAN1, 0x92C, 17) 122 }; 123 124 static struct aw_ccung_gate ccu_d1_gates[] = { 125 CCU_GATE(CLK_BUS_DE, "bus-de", "psi-ahb", 0x60C, 0) 126 CCU_GATE(CLK_BUS_DI, "bus-di", "psi-ahb", 0x62C, 0) 127 CCU_GATE(CLK_BUS_G2D, "bus-g2d", "psi-ahb", 0x63C, 0) 128 CCU_GATE(CLK_BUS_CE, "bus-ce", "psi-ahb", 0x68C, 0) 129 CCU_GATE(CLK_BUS_VE, "bus-ve", "psi-ahb", 0x690, 0) 130 CCU_GATE(CLK_BUS_DMA, "bus-dma", "psi-ahb", 0x70C, 0) 131 CCU_GATE(CLK_BUS_MSGBOX0, "bus-msgbox0", "psi-ahb", 0x71C, 0) 132 CCU_GATE(CLK_BUS_MSGBOX1, "bus-msgbox1", "psi-ahb", 0x71C, 1) 133 CCU_GATE(CLK_BUS_MSGBOX2, "bus-msgbox2", "psi-ahb", 0x71C, 2) 134 CCU_GATE(CLK_BUS_SPINLOCK, "bus-spinlock", "psi-ahb", 0x72C, 0) 135 CCU_GATE(CLK_BUS_HSTIMER, "bus-hstimer", "psi-ahb", 0x73C, 0) 136 CCU_GATE(CLK_AVS, "avs", "dcxo", 0x740, 31) 137 CCU_GATE(CLK_BUS_DBG, "bus-dbg", "psi-ahb", 0x78C, 0) 138 CCU_GATE(CLK_BUS_PWM, "bus-pwm", "psi-ahb", 0x7AC, 0) 139 CCU_GATE(CLK_BUS_IOMMU, "bus-iommu", "apb0", 0x7BC, 0) 140 CCU_GATE(CLK_MBUS_DMA, "mbus-dma", "mbus", 0x804, 0) 141 CCU_GATE(CLK_MBUS_VE, "mbus-ve", "mbus", 0x804, 1) 142 CCU_GATE(CLK_MBUS_CE, "mbus-ce", "mbus", 0x804, 2) 143 CCU_GATE(CLK_MBUS_TVIN, "mbus-tvin", "mbus", 0x804, 7) 144 CCU_GATE(CLK_MBUS_CSI, "mbus-csi", "mbus", 0x804, 8) 145 CCU_GATE(CLK_MBUS_G2D, "mbus-g2d", "mbus", 0x804, 10) 146 CCU_GATE(CLK_MBUS_RISCV, "mbus-riscv", "mbus", 0x804, 11) 147 CCU_GATE(CLK_BUS_DRAM, "bus-dram", "psi-ahb", 0x80C, 0) 148 CCU_GATE(CLK_BUS_MMC0, "bus-mmc0", "psi-ahb", 0x84C, 0) 149 CCU_GATE(CLK_BUS_MMC1, "bus-mmc1", "psi-ahb", 0x84C, 1) 150 CCU_GATE(CLK_BUS_MMC2, "bus-mmc2", "psi-ahb", 0x84C, 2) 151 CCU_GATE(CLK_BUS_UART0, "bus-uart0", "apb1", 0x90C, 0) 152 CCU_GATE(CLK_BUS_UART1, "bus-uart1", "apb1", 0x90C, 1) 153 CCU_GATE(CLK_BUS_UART2, "bus-uart2", "apb1", 0x90C, 2) 154 CCU_GATE(CLK_BUS_UART3, "bus-uart3", "apb1", 0x90C, 3) 155 CCU_GATE(CLK_BUS_UART4, "bus-uart4", "apb1", 0x90C, 4) 156 CCU_GATE(CLK_BUS_UART5, "bus-uart5", "apb1", 0x90C, 5) 157 CCU_GATE(CLK_BUS_I2C0, "bus-i2c0", "apb1", 0x91C, 0) 158 CCU_GATE(CLK_BUS_I2C1, "bus-i2c1", "apb1", 0x91C, 1) 159 CCU_GATE(CLK_BUS_I2C2, "bus-i2c2", "apb1", 0x91C, 2) 160 CCU_GATE(CLK_BUS_I2C3, "bus-i2c3", "apb1", 0x91C, 3) 161 CCU_GATE(CLK_BUS_SPI0, "bus-spi0", "psi-ahb", 0x96C, 0) 162 CCU_GATE(CLK_BUS_SPI1, "bus-spi1", "psi-ahb", 0x96C, 1) 163 CCU_GATE(CLK_BUS_EMAC, "bus-emac", "psi-ahb", 0x97C, 0) 164 CCU_GATE(CLK_BUS_IR_TX, "bus-ir-tx", "apb0", 0x9CC, 0) 165 CCU_GATE(CLK_BUS_GPADC, "bus-gpadc", "apb0", 0x9EC, 0) 166 CCU_GATE(CLK_BUS_THS, "bus-ths", "apb0", 0x9FC, 0) 167 CCU_GATE(CLK_BUS_I2S0, "bus-i2s0", "apb0", 0xA10, 0) 168 CCU_GATE(CLK_BUS_I2S1, "bus-i2s1", "apb0", 0xA10, 1) 169 CCU_GATE(CLK_BUS_I2S2, "bus-i2s2", "apb0", 0xA10, 2) 170 CCU_GATE(CLK_BUS_SPDIF, "bus-spdif", "apb0", 0xA2C, 0) 171 CCU_GATE(CLK_BUS_DMIC, "bus-dmic", "apb0", 0xA4C, 0) 172 CCU_GATE(CLK_BUS_AUDIO, "bus-audio", "apb0", 0xA5C, 0) 173 CCU_GATE(CLK_BUS_OHCI0, "bus-ohci0", "psi-ahb", 0xA8C, 0) 174 CCU_GATE(CLK_BUS_OHCI1, "bus-ohci1", "psi-ahb", 0xA8C, 1) 175 CCU_GATE(CLK_BUS_EHCI0, "bus-ehci0", "psi-ahb", 0xA8C, 4) 176 CCU_GATE(CLK_BUS_EHCI1, "bus-ehci1", "psi-ahb", 0xA8C, 5) 177 CCU_GATE(CLK_BUS_OTG, "bus-otg", "psi-ahb", 0xA8C, 8) 178 CCU_GATE(CLK_BUS_LRADC, "bus-lradc", "apb0", 0xA9C, 0) 179 CCU_GATE(CLK_BUS_DPSS_TOP, "bus-dpss-top", "psi-ahb", 0xABC, 0) 180 CCU_GATE(CLK_BUS_MIPI_DSI, "bus-mipi-dsi", "psi-ahb", 0xB4C, 0) 181 CCU_GATE(CLK_BUS_TCON_LCD0, "bus-tcon-lcd0", "psi-ahb", 0xB7C, 0) 182 CCU_GATE(CLK_BUS_TCON_TV, "bus-tcon-tv", "psi-ahb", 0xB9C, 0) 183 CCU_GATE(CLK_BUS_TVE_TOP, "bus-tve-top", "psi-ahb", 0xBBC, 0) 184 CCU_GATE(CLK_BUS_TVE, "bus-tve", "psi-ahb", 0xBBC, 1) 185 CCU_GATE(CLK_BUS_TVD_TOP, "bus-tvd-top", "psi-ahb", 0xBDC, 0) 186 CCU_GATE(CLK_BUS_TVD, "bus-tvd", "psi-ahb", 0xBDC, 1) 187 CCU_GATE(CLK_BUS_LEDC, "bus-ledc", "psi-ahb", 0xBFC, 0) 188 CCU_GATE(CLK_BUS_CSI, "bus-csi", "psi-ahb", 0xC1C, 0) 189 CCU_GATE(CLK_BUS_TPADC, "bus-tpadc", "apb0", 0xC5C, 0) 190 CCU_GATE(CLK_BUS_TZMA, "bus-tzma", "apb0", 0xC6C, 0) 191 CCU_GATE(CLK_BUS_DSP_CFG, "bus-dsp-cfg", "psi-ahb", 0xC7C, 1) 192 CCU_GATE(CLK_BUS_RISCV_CFG, "bus-riscv-cfg", "psi-ahb", 0xD0C, 0) 193 CCU_GATE(CLK_BUS_CAN0, "bus-can0", "apb1", 0x92C, 0) 194 CCU_GATE(CLK_BUS_CAN1, "bus-can1", "apb1", 0x92C, 1) 195 }; 196 197 static const char *pll_cpux_parents[] = { "dcxo" }; 198 NP_CLK(pll_cpux_clk, 199 CLK_PLL_CPUX, /* id */ 200 "pll_cpux", /* name */ 201 pll_cpux_parents, /* parents */ 202 0x0, /* offset */ 203 8, 8, 0, 0, /* n factor */ 204 0, 2, 0, 0, /* p factor */ 205 27, /* gate */ 206 28, 1000, /* lock */ 207 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 208 209 static const char *pll_ddr0_parents[] = { "dcxo" }; 210 NMM_CLK(pll_ddr0_clk, 211 CLK_PLL_DDR0, /* id */ 212 "pll_ddr0", /* name */ 213 pll_ddr0_parents, /* parents */ 214 0x10, /* offset */ 215 8, 7, 0, 0, /* n factor */ 216 0, 1, 0, 0, /* m0 factor */ 217 1, 1, 0, 0, /* m1 factor */ 218 27, /* gate */ 219 28, 1000, /* lock */ 220 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 221 222 /* PLL_PERIPH(4X) = 24 MHz * N / M1 / M0 */ 223 static const char *pll_periph0_4x_parents[] = { "dcxo" }; 224 NMM_CLK(pll_periph0_4x_clk, 225 CLK_PLL_PERIPH0_4X, /* id */ 226 "pll_periph0_4x", /* name */ 227 pll_periph0_4x_parents, /* parents */ 228 0x20, /* offset */ 229 8, 8, 0, 0, /* n factor */ 230 0, 1, 0, 0, /* m0 factor */ 231 1, 1, 0, 0, /* m1 factor */ 232 27, /* gate */ 233 28, 1000, /* lock */ 234 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 235 236 /* PLL_PERIPH0(2X) = 24 MHz * N / M / P0 */ 237 static const char *pll_periph0_2x_parents[] = { "pll_periph0_4x" }; 238 M_CLK(pll_periph0_2x_clk, 239 CLK_PLL_PERIPH0_2X, /* id */ 240 "pll_periph0_2x", /* name */ 241 pll_periph0_2x_parents, /* parents */ 242 0x20, /* offset */ 243 16, 3, 0, 0, /* m factor */ 244 0, 0, /* mux */ 245 0, /* gate */ 246 0); /* flags */ 247 248 /* PLL_PERIPH0(800M) = 24 MHz * N / M / P1 */ 249 static const char *pll_periph0_800m_parents[] = { "pll_periph0_4x" }; 250 M_CLK(pll_periph0_800m_clk, 251 CLK_PLL_PERIPH0_800M, /* id */ 252 "pll_periph0_800m", /* name */ 253 pll_periph0_800m_parents, /* parents */ 254 0x20, /* offset */ 255 20, 3, 0, 0, /* m factor */ 256 0, 0, /* mux */ 257 0, /* gate */ 258 0); /* flags */ 259 260 /* PLL_PERIPH0(1X) = 24 MHz * N / M / P0 / 2 */ 261 static const char *pll_periph0_parents[] = { "pll_periph0_2x" }; 262 FIXED_CLK(pll_periph0_clk, 263 CLK_PLL_PERIPH0, /* id */ 264 "pll_periph0", /* name */ 265 pll_periph0_parents, /* parents */ 266 0, /* freq */ 267 1, /* mult */ 268 2, /* div */ 269 0); /* flags */ 270 271 /* For child clocks: InputFreq * N / M */ 272 static const char *pll_video0_parents[] = { "dcxo" }; 273 NP_CLK(pll_video0_clk, 274 CLK_PLL_VIDEO0, /* id */ 275 "pll_video0", /* name */ 276 pll_video0_parents, /* parents */ 277 0x40, /* offset */ 278 8, 7, 0, 0, /* n factor */ 279 1, 1, 0, 0, /* p factor */ 280 27, /* gate */ 281 28, 1000, /* lock */ 282 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 283 284 /* PLL_VIDEO0(4X) = InputFreq * N / M / D */ 285 /* D is only for testing */ 286 static const char *pll_video0_4x_parents[] = { "pll_video0" }; 287 M_CLK(pll_video0_4x_clk, 288 CLK_PLL_VIDEO0_4X, /* id */ 289 "pll_video0_4x", /* name */ 290 pll_video0_4x_parents, /* parents */ 291 0x40, /* offset */ 292 0, 1, 0, 0, /* m factor */ 293 0, 0, /* mux */ 294 0, /* gate */ 295 0); /* flags */ 296 297 /* PLL_VIDEO0(2X) = InputFreq * N / M / 2 */ 298 static const char *pll_video0_2x_parents[] = { "pll_video0" }; 299 FIXED_CLK(pll_video0_2x_clk, 300 CLK_PLL_VIDEO0_2X, /* id */ 301 "pll_video0_2x", /* name */ 302 pll_video0_2x_parents, /* parents */ 303 0, /* freq */ 304 1, /* mult */ 305 2, /* div */ 306 0); /* flags */ 307 308 /* For child clocks: InputFreq * N / M */ 309 static const char *pll_video1_parents[] = { "dcxo" }; 310 NP_CLK(pll_video1_clk, 311 CLK_PLL_VIDEO1, /* id */ 312 "pll_video1", /* name */ 313 pll_video1_parents, /* parents */ 314 0x48, /* offset */ 315 8, 7, 0, 0, /* n factor */ 316 1, 1, 0, 0, /* p factor */ 317 27, /* gate */ 318 28, 1000, /* lock */ 319 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 320 321 /* PLL_VIDEO1(4X) = InputFreq * N / M / D */ 322 /* D is only for testing */ 323 static const char *pll_video1_4x_parents[] = { "pll_video1" }; 324 M_CLK(pll_video1_4x_clk, 325 CLK_PLL_VIDEO1_4X, /* id */ 326 "pll_video1_4x", /* name */ 327 pll_video1_4x_parents, /* parents */ 328 0x48, /* offset */ 329 0, 1, 0, 0, /* m factor */ 330 0, 0, /* mux */ 331 0, /* gate */ 332 0); /* flags */ 333 334 /* PLL_VIDEO1(2X) = InputFreq * N / M / 2 */ 335 static const char *pll_video1_2x_parents[] = { "pll_video1" }; 336 FIXED_CLK(pll_video1_2x_clk, 337 CLK_PLL_VIDEO1_2X, /* id */ 338 "pll_video1_2x", /* name */ 339 pll_video1_2x_parents, /* parents */ 340 0, /* freq */ 341 1, /* mult */ 342 2, /* div */ 343 0); /* flags */ 344 345 static const char *pll_ve_parents[] = { "dcxo" }; 346 NMM_CLK(pll_ve_clk, 347 CLK_PLL_VE, /* id */ 348 "pll_ve", /* name */ 349 pll_ve_parents, /* parents */ 350 0x58, /* offset */ 351 8, 7, 0, 0, /* n factor */ 352 0, 1, 0, 0, /* m0 factor */ 353 1, 1, 0, 0, /* m1 factor */ 354 27, /* gate */ 355 28, 1000, /* lock */ 356 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 357 358 /* For child clocks: 24MHz * N / M1 / M0 */ 359 static const char *pll_audio0_4x_parents[] = { "dcxo" }; 360 NMM_CLK(pll_audio0_4x_clk, 361 CLK_PLL_AUDIO0_4X, /* id */ 362 "pll_audio0_4x", /* name */ 363 pll_audio0_4x_parents, /* parents */ 364 0x78, /* offset */ 365 8, 7, 0, 0, /* n factor */ 366 0, 1, 0, 0, /* m0 factor */ 367 1, 1, 0, 0, /* m1 factor */ 368 27, /* gate */ 369 28, 1000, /* lock */ 370 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 371 372 /* PLL_AUDIO0(2X) = (24MHz * N / M1 / M0) / P / 2 */ 373 static const char *pll_audio0_2x_parents[] = { "pll_audio0_4x" }; 374 FIXED_CLK(pll_audio0_2x_clk, 375 CLK_PLL_AUDIO0_2X, /* id */ 376 "pll_audio0_2x", /* name */ 377 pll_audio0_2x_parents, /* parents */ 378 0, /* freq */ 379 1, /* mult */ 380 2, /* div */ 381 0); /* flags */ 382 383 /* PLL_AUDIO0(1X) = 24MHz * N / M1 / M0 / P / 2 */ 384 static const char *pll_audio0_parents[] = { "pll_audio0_2x" }; 385 FIXED_CLK(pll_audio0_clk, 386 CLK_PLL_AUDIO0, /* id */ 387 "pll_audio0", /* name */ 388 pll_audio0_parents, /* parents */ 389 0, /* freq */ 390 1, /* mult */ 391 2, /* div */ 392 0); /* flags */ 393 394 /* For child clocks: 24MHz * N / M */ 395 static const char *pll_audio1_parents[] = { "dcxo" }; 396 NP_CLK(pll_audio1_clk, 397 CLK_PLL_AUDIO1, /* id */ 398 "pll_audio1", /* name */ 399 pll_audio1_parents, /* parents */ 400 0x80, /* offset */ 401 8, 7, 0, 0, /* n factor */ 402 1, 1, 0, 0, /* p factor */ 403 27, /* gate */ 404 28, 1000, /* lock */ 405 AW_CLK_HAS_GATE | AW_CLK_HAS_LOCK); /* flags */ 406 407 /* PLL_AUDIO1(DIV2) = 24MHz * N / M / P0 */ 408 static const char *pll_audio1_div2_parents[] = { "pll_audio1" }; 409 M_CLK(pll_audio1_div2_clk, 410 CLK_PLL_AUDIO1_DIV2, /* id */ 411 "pll_audio1_div2", /* name */ 412 pll_audio1_div2_parents, /* parents */ 413 0x80, /* offset */ 414 16, 3, 0, 0, /* m factor */ 415 0, 0, /* mux */ 416 0, /* gate */ 417 0); /* flags */ 418 419 /* PLL_AUDIO1(DIV5) = 24MHz * N / M / P1 */ 420 static const char *pll_audio1_div5_parents[] = { "pll_audio1" }; 421 M_CLK(pll_audio1_div5_clk, 422 CLK_PLL_AUDIO1_DIV5, /* id */ 423 "pll_audio1_div5", /* name */ 424 pll_audio1_div5_parents, /* parents */ 425 0x80, /* offset */ 426 20, 3, 0, 0, /* m factor */ 427 0, 0, /* mux */ 428 0, /* gate */ 429 0); /* flags */ 430 431 static const char *cpux_parents[] = { "dcxo", "osc32k", "iosc", "pll_cpux", 432 "pll_periph0", "pll_periph0_2x", "pll_periph0_800m" }; 433 M_CLK(cpux_clk, 434 CLK_CPUX, /* id */ 435 "cpux", /* name */ 436 cpux_parents, /* parents */ 437 0x500, /* offset */ 438 16, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* m factor */ 439 24, 3, /* mux */ 440 0, /* gate */ 441 AW_CLK_HAS_MUX | AW_CLK_SET_PARENT); /* flags */ 442 443 static const char *cpux_axi_parents[] = { "cpux" }; 444 M_CLK(cpux_axi_clk, 445 CLK_CPUX_AXI, /* id */ 446 "cpux_axi", /* name */ 447 cpux_axi_parents, /* parents */ 448 0x500, /* offset */ 449 0, 2, 0, 0, /* m factor */ 450 0, 0, /* mux */ 451 0, /* gate */ 452 0); /* flags */ 453 454 static const char *cpux_apb_parents[] = { "cpux" }; 455 M_CLK(cpux_apb_clk, 456 CLK_CPUX_APB, /* id */ 457 "cpux_apb", /* name */ 458 cpux_apb_parents, /* parents */ 459 0x500, /* offset */ 460 8, 2, 0, 0, /* m factor */ 461 0, 0, /* mux */ 462 0, /* gate */ 463 0); /* flags */ 464 465 static const char *psi_ahb_parents[] = { "dcxo", "osc32k", "iosc", 466 "pll_periph0" }; 467 NM_CLK(psi_ahb_clk, 468 CLK_PSI_AHB, "psi-ahb", psi_ahb_parents, /* id, name, parents */ 469 0x510, /* offset */ 470 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 471 0, 2, 0, 0, /* m factor */ 472 24, 2, /* mux */ 473 0, /* gate */ 474 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 475 476 static const char *apb0_parents[] = { "dcxo", "osc32k", "psi-ahb", "pll_periph0" }; 477 NM_CLK(apb0_clk, 478 CLK_APB0, "apb0", apb0_parents, /* id, name, parents */ 479 0x520, /* offset */ 480 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 481 0, 2, 0, 0, /* m factor */ 482 24, 2, /* mux */ 483 0, /* gate */ 484 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 485 486 static const char *apb1_parents[] = { "dcxo", "osc32k", "psi-ahb", "pll_periph0" }; 487 NM_CLK(apb1_clk, 488 CLK_APB1, "apb1", apb1_parents, /* id, name, parents */ 489 0x524, /* offset */ 490 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 491 0, 2, 0, 0, /* m factor */ 492 24, 2, /* mux */ 493 0, /* gate */ 494 AW_CLK_HAS_MUX | AW_CLK_REPARENT); /* flags */ 495 496 static const char *mbus_parents[] = { "dram" }; 497 FIXED_CLK(mbus_clk, 498 CLK_MBUS, "mbus", mbus_parents, /* id, name, parents */ 499 0, /* freq */ 500 1, /* mult */ 501 4, /* div */ 502 0); /* flags */ 503 504 static const char *de_parents[] = { "pll_periph0_2x", "pll_video0_4x", 505 "pll_video1_4x", "pll_audio1_div2" }; 506 M_CLK(de_clk, 507 CLK_DE, "de", de_parents, /* id, name, parents */ 508 0x600, /* offset */ 509 0, 5, 0, 0, /* m factor */ 510 24, 3, /* mux */ 511 31, /* gate */ 512 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 513 AW_CLK_REPARENT); /* flags */ 514 515 static const char *di_parents[] = { "pll_periph0_2x", "pll_video0_4x", 516 "pll_video1_4x", "pll_audio1_div2" }; 517 M_CLK(di_clk, 518 CLK_DI, "di", di_parents, /* id, name, parents */ 519 0x620, /* offset */ 520 0, 5, 0, 0, /* m factor */ 521 24, 3, /* mux */ 522 31, /* gate */ 523 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 524 AW_CLK_REPARENT); /* flags */ 525 526 static const char *g2d_parents[] = { "pll_periph0_2x", "pll_video0_4x", 527 "pll_video1_4x", "pll_audio1_div2" }; 528 M_CLK(g2d_clk, 529 CLK_G2D, "g2d", g2d_parents, /* id, name, parents */ 530 0x630, /* offset */ 531 0, 5, 0, 0, /* m factor */ 532 24, 3, /* mux */ 533 31, /* gate */ 534 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 535 AW_CLK_REPARENT); /* flags */ 536 537 static const char *ce_parents[] = { "dcxo", "pll_periph0_2x", "pll_periph0" }; 538 NM_CLK(ce_clk, 539 CLK_CE, "ce", ce_parents, /* id, name, parents */ 540 0x680, /* offset */ 541 8, 2, 0, 0, /* n factor */ 542 0, 4, 0, 0, /* m factor */ 543 24, 3, /* mux */ 544 31, /* gate */ 545 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 546 AW_CLK_REPARENT); /* flags */ 547 548 static const char *ve_parents[] = { "pll_ve", "pll_periph0_2x" }; 549 M_CLK(ve_clk, 550 CLK_VE, "ve", ve_parents, /* id, name, parents */ 551 0x690, /* offset */ 552 0, 5, 0, 0, /* m factor */ 553 24, 1, /* mux */ 554 31, /* gate */ 555 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | /* flags */ 556 AW_CLK_REPARENT); 557 558 static const char *dram_parents[] = { "pll_ddr0", "pll_audio1_div2", 559 "pll_periph0_2x", "pll_periph0_800m" }; 560 NM_CLK(dram_clk, 561 CLK_DRAM, "dram", dram_parents, /* id, name, parents */ 562 0x800, /* offset */ 563 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 564 0, 2, 0, 0, /* m factor */ 565 24, 3, /* mux */ 566 31, /* gate */ 567 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | /* flags */ 568 AW_CLK_REPARENT); 569 570 /* SMHC0 */ 571 static const char *mmc0_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x", 572 "pll_audio1_div2" }; 573 NM_CLK(mmc0_clk, 574 CLK_MMC0, "mmc0", mmc0_parents, /* id, name, parents */ 575 0x830, /* offset */ 576 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 577 0, 4, 0, 0, /* m factor */ 578 24, 3, /* mux */ 579 31, /* gate */ 580 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 581 AW_CLK_REPARENT); /* flags */ 582 583 /* SMHC1 */ 584 static const char *mmc1_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x", 585 "pll_audio1_div2" }; 586 NM_CLK(mmc1_clk, 587 CLK_MMC1, "mmc1", mmc1_parents, /* id, name, parents */ 588 0x834, /* offset */ 589 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 590 0, 4, 0, 0, /* m factor */ 591 24, 3, /* mux */ 592 31, /* gate */ 593 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 594 AW_CLK_REPARENT); /* flags */ 595 596 /* SMHC2 */ 597 static const char *mmc2_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x", 598 "pll_periph0_800m", "pll_audio1_div2" }; 599 NM_CLK(mmc2_clk, 600 CLK_MMC2, "mmc2", mmc2_parents, /* id, name, parents */ 601 0x838, /* offset */ 602 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 603 0, 4, 0, 0, /* m factor */ 604 24, 3, /* mux */ 605 31, /* gate */ 606 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 607 AW_CLK_REPARENT); /* flags */ 608 609 static const char *spi0_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x", 610 "pll_audio1_div2", "pll_audio1_div5" }; 611 NM_CLK(spi0_clk, 612 CLK_SPI0, "spi0", spi0_parents, /* id, name, parents */ 613 0x940, /* offset */ 614 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 615 0, 4, 0, 0, /* m factor */ 616 24, 3, /* mux */ 617 31, /* gate */ 618 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 619 AW_CLK_REPARENT); /* flags */ 620 621 static const char *spi1_parents[] = { "dcxo", "pll_periph0", "pll_periph0_2x", 622 "pll_audio1_div2", "pll_audio1_div5" }; 623 NM_CLK(spi1_clk, 624 CLK_SPI1, "spi1", spi1_parents, /* id, name, parents */ 625 0x944, /* offset */ 626 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 627 0, 4, 0, 0, /* m factor */ 628 24, 3, /* mux */ 629 31, /* gate */ 630 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 631 AW_CLK_REPARENT); /* flags */ 632 633 /* Use M_CLK to have gate */ 634 static const char *emac_25m_parents[] = { "pll_periph0" }; 635 M_CLK(emac_25m_clk, 636 CLK_EMAC_25M, /* id */ 637 "emac_25m", /* name */ 638 emac_25m_parents, /* parents */ 639 0x970, /* offset */ 640 0, 0, 24, AW_CLK_FACTOR_FIXED, /* m factor */ 641 0, 0, /* mux */ 642 31, /* gate */ 643 AW_CLK_HAS_GATE | AW_CLK_REPARENT); /* flags */ 644 645 static const char *irtx_parents[] = { "dcxo", "pll_periph0" }; 646 NM_CLK(irtx_clk, 647 CLK_IR_TX, "irtx", irtx_parents, /* id, name, parents */ 648 0x9C0, /* offset */ 649 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 650 0, 4, 0, 0, /* m factor */ 651 24, 3, /* mux */ 652 31, /* gate */ 653 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 654 AW_CLK_REPARENT); /* flags */ 655 656 static const char *i2s0_parents[] = { "pll_audio0", "pll_audio0_4x", 657 "pll_audio1_div2", "pll_audio1_div5" }; 658 NM_CLK(i2s0_clk, 659 CLK_I2S0, "i2s0", i2s0_parents, /* id, name, parents */ 660 0xA10, /* offset */ 661 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 662 0, 5, 0, 0, /* m factor */ 663 24, 3, /* mux */ 664 31, /* gate */ 665 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 666 AW_CLK_REPARENT); /* flags */ 667 668 static const char *i2s1_parents[] = { "pll_audio0", "pll_audio0_4x", 669 "pll_audio1_div2", "pll_audio1_div5" }; 670 NM_CLK(i2s1_clk, 671 CLK_I2S1, "i2s1", i2s1_parents, /* id, name, parents */ 672 0xA14, /* offset */ 673 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 674 0, 5, 0, 0, /* m factor */ 675 24, 3, /* mux */ 676 31, /* gate */ 677 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 678 AW_CLK_REPARENT); /* flags */ 679 680 static const char *i2s2_parents[] = { "pll_audio0", "pll_audio0_4x", 681 "pll_audio1_div2", "pll_audio1_div5" }; 682 NM_CLK(i2s2_clk, 683 CLK_I2S2, "i2s2", i2s2_parents, /* id, name, parents */ 684 0xA18, /* offset */ 685 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 686 0, 5, 0, 0, /* m factor */ 687 24, 3, /* mux */ 688 31, /* gate */ 689 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 690 AW_CLK_REPARENT); /* flags */ 691 692 static const char *i2s2_asrc_parents[] = { "pll_audio0_4x", "pll_periph0", 693 "pll_audio1_div2", "pll_audio1_div5" }; 694 NM_CLK(i2s2_asrc_clk, 695 CLK_I2S2_ASRC, /* id */ 696 "i2s2_asrc", /* name */ 697 i2s2_asrc_parents, /* parents */ 698 0xA1C, /* offset */ 699 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 700 0, 5, 0, 0, /* m factor */ 701 24, 3, /* mux */ 702 31, /* gate */ 703 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 704 AW_CLK_REPARENT); /* flags */ 705 706 /* OWA_TX */ 707 static const char *spdif_tx_parents[] = { "pll_audio0", "pll_audio0_4x", 708 "pll_audio1_div2", "pll_audio1_div5" }; 709 NM_CLK(spdif_tx_clk, 710 CLK_SPDIF_TX, "spdif_tx", spdif_tx_parents, /* id, name, parents */ 711 0xA24, /* offset */ 712 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 713 0, 5, 0, 0, /* m factor */ 714 24, 3, /* mux */ 715 31, /* gate */ 716 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 717 AW_CLK_REPARENT); /* flags */ 718 719 /* OWA_RX */ 720 static const char *spdif_rx_parents[] = { "pll_periph0", "pll_audio1_div2", 721 "pll_audio1_div5" }; 722 NM_CLK(spdif_rx_clk, 723 CLK_SPDIF_RX, "spdif_rx", spdif_rx_parents, /* id, name, parents */ 724 0xA28, /* offset */ 725 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 726 0, 5, 0, 0, /* m factor */ 727 24, 3, /* mux */ 728 31, /* gate */ 729 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 730 AW_CLK_REPARENT); /* flags */ 731 732 static const char *dmic_parents[] = { "pll_audio0", "pll_audio1_div2", 733 "pll_audio1_div5" }; 734 NM_CLK(dmic_clk, 735 CLK_DMIC, "dmic", dmic_parents, /* id, name, parents */ 736 0xA40, /* offset */ 737 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 738 0, 5, 0, 0, /* m factor */ 739 24, 3, /* mux */ 740 31, /* gate */ 741 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 742 AW_CLK_REPARENT); /* flags */ 743 744 static const char *audio_dac_parents[] = { "pll_audio0", "pll_audio1_div2", 745 "pll_audio1_div5" }; 746 NM_CLK(audio_dac_clk, 747 CLK_AUDIO_DAC, /* id */ 748 "audio_dac", /* name */ 749 audio_dac_parents, /* parents */ 750 0xA50, /* offset */ 751 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 752 0, 5, 0, 0, /* m factor */ 753 24, 3, /* mux */ 754 31, /* gate */ 755 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 756 AW_CLK_REPARENT); /* flags */ 757 758 static const char *audio_adc_parents[] = { "pll_audio0", "pll_audio1_div2", 759 "pll_audio1_div5" }; 760 NM_CLK(audio_adc_clk, 761 CLK_AUDIO_ADC, /* id */ 762 "audio_adc", /* name */ 763 audio_adc_parents, /* parents */ 764 0xA54, /* offset */ 765 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 766 0, 5, 0, 0, /* m factor */ 767 24, 3, /* mux */ 768 31, /* gate */ 769 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 770 AW_CLK_REPARENT); /* flags */ 771 772 /* 773 * XXX: These USB clocks are unusual, and can't be modeled fully with any of 774 * our existing clk classes. 775 * 776 * The clocks have three parents; they output 12M when assigned to the first 777 * two, and the third is direct (32K). 778 * 779 * Thus a divider table like the following would be needed: 780 * struct clk_div_table usb_ohci_div_table[] = { 781 * { .value = 0, .divider = 50 }, 782 * { .value = 1, .divider = 2 }, 783 * { .value = 2, .divider = 1 }, 784 * { }, 785 * }; 786 * 787 * But we also require a gate. 788 * 789 * To work around this, model the clocks as if they had only one parent. 790 */ 791 static const char *usb_ohci_parents[] = { "pll_periph0", 792 /*"dcxo", "osc32k"*/ }; 793 M_CLK(usb_ohci0_clk, 794 CLK_USB_OHCI0, /* id */ 795 "usb_ohci0", /* name */ 796 usb_ohci_parents, /* parents */ 797 0xA70, /* offset */ 798 0, 0, 50, AW_CLK_FACTOR_FIXED, /* m factor */ 799 24, 2, /* mux */ 800 31, /* gate */ 801 AW_CLK_HAS_GATE /* | AW_CLK_HAS_MUX */); /* flags */ 802 803 M_CLK(usb_ohci1_clk, 804 CLK_USB_OHCI1, /* id */ 805 "usb_ohci1", /* name */ 806 usb_ohci_parents, /* parents */ 807 0xA74, /* offset */ 808 0, 0, 50, AW_CLK_FACTOR_FIXED, /* m factor */ 809 24, 2, /* mux */ 810 31, /* gate */ 811 AW_CLK_HAS_GATE /* | AW_CLK_HAS_MUX */); /* flags */ 812 813 814 static const char *dsi_parents[] = { "dcxo", "pll_periph0", "pll_video0_2x", 815 "pll_video1_2x", "pll_audio1_div2" }; 816 M_CLK(dsi_clk, 817 CLK_MIPI_DSI, "mipi-dsi", dsi_parents, /* id, name, parents */ 818 0xB24, /* offset */ 819 0, 4, 0, 0, /* m factor */ 820 24, 3, /* mux */ 821 31, /* gate */ 822 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 823 AW_CLK_REPARENT); /* flags */ 824 825 static const char *tconlcd_parents[] = { "pll_video0", "pll_video0_4x", 826 "pll_video1", "pll_video1_4x", "pll_periph0_2x", "pll_audio1_div2" }; 827 NM_CLK(tconlcd_clk, 828 CLK_TCON_LCD0, "tcon-lcd0", tconlcd_parents, /* id, name, parents */ 829 0xB60, /* offset */ 830 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 831 0, 4, 0, 0, /* m factor */ 832 24, 3, /* mux */ 833 31, /* gate */ 834 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 835 AW_CLK_REPARENT); /* flags */ 836 837 static const char *tcontv_parents[] = { "pll_video0", "pll_video0_4x", 838 "pll_video1", "pll_video1_4x", "pll_periph0_2x", "pll_audio1_div2" }; 839 NM_CLK(tcontv_clk, 840 CLK_TCON_TV, "tcon-tv", tcontv_parents, /* id, name, parents */ 841 0xB80, /* offset */ 842 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 843 0, 4, 0, 0, /* m factor */ 844 24, 3, /* mux */ 845 31, /* gate */ 846 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 847 AW_CLK_REPARENT); /* flags */ 848 849 static const char *tve_parents[] = { "pll_video0", "pll_video0_4x", 850 "pll_video1", "pll_video1_4x", "pll_periph0_2x", "pll_audio1_div2" }; 851 NM_CLK(tve_clk, 852 CLK_TVE, "tve", tve_parents, /* id, name, parents */ 853 0xBB0, /* offset */ 854 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 855 0, 4, 0, 0, /* m factor */ 856 24, 3, /* mux */ 857 31, /* gate */ 858 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 859 AW_CLK_REPARENT); /* flags */ 860 861 static const char *tvd_parents[] = { "dcxo", "pll_video0", "pll_video1", 862 "pll_periph0" }; 863 M_CLK(tvd_clk, 864 CLK_TVD, "tvd", tvd_parents, /* id, name, parents */ 865 0xBC0, /* offset */ 866 0, 5, 0, 0, /* m factor */ 867 24, 3, /* mux */ 868 31, /* gate */ 869 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 870 AW_CLK_REPARENT); /* flags */ 871 872 static const char *ledc_parents[] = { "dcxo", "pll_periph0" }; 873 NM_CLK(ledc_clk, 874 CLK_LEDC, "ledc", ledc_parents, /* id, name, parents */ 875 0xBF0, /* offset */ 876 8, 2, 0, AW_CLK_FACTOR_POWER_OF_TWO, /* n factor */ 877 0, 4, 0, 0, /* m factor */ 878 24, 1, /* mux */ 879 31, /* gate */ 880 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 881 AW_CLK_REPARENT); /* flags */ 882 883 static const char *csi_top_parents[] = { "pll_periph0_2x", "pll_video0_2x", 884 "pll_video1_2x" }; 885 M_CLK(csi_top_clk, 886 CLK_CSI_TOP, "csi-top", csi_top_parents, /* id, name, parents */ 887 0xC04, /* offset */ 888 0, 4, 0, 0, /* m factor */ 889 24, 3, /* mux */ 890 31, /* gate */ 891 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 892 AW_CLK_REPARENT); /* flags */ 893 894 static const char *csi_mclk_parents[] = { "dcxo", "pll_periph0", 895 "pll_video0", "pll_video1", "pll_audio1_div2", "pll_audio1_div5" }; 896 M_CLK(csi_mclk, 897 CLK_CSI_MCLK, /* id */ 898 "csi-mclk", /* name */ 899 csi_mclk_parents, /* parents */ 900 0xC08, /* offset */ 901 0, 5, 0, 0, /* m factor */ 902 24, 3, /* mux */ 903 31, /* gate */ 904 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 905 AW_CLK_REPARENT); /* flags */ 906 907 /* Use M_CLK to have mux and gate */ 908 static const char *tpadc_parents[] = { "dcxo", "pll_audio0" }; 909 M_CLK(tpadc_clk, 910 CLK_TPADC, "tpadc", tpadc_parents, /* id, name, parents */ 911 0xC50, /* offset */ 912 0, 0, 1, AW_CLK_FACTOR_FIXED, /* m factor */ 913 24, 2, /* mux */ 914 31, /* gate */ 915 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 916 AW_CLK_REPARENT); /* flags */ 917 918 static const char *dsp_parents[] = { "dcxo", "osc32k", "iosc", 919 "pll_periph0_2x", "pll_audio1_div2" }; 920 M_CLK(dsp_clk, 921 CLK_DSP, "dsp", dsp_parents, /* id, name, parents */ 922 0xC70, /* offset */ 923 0, 5, 0, 0, /* m factor */ 924 24, 3, /* mux */ 925 31, /* gate */ 926 AW_CLK_HAS_GATE | AW_CLK_HAS_MUX | 927 AW_CLK_REPARENT); /* flags */ 928 929 static const char *riscv_parents[] = { "dcxo", "osc32k", "iosc", 930 "pll_periph0_800m", "pll_periph0", "pll_cpux", "pll_audio1_div2" }; 931 M_CLK(riscv_clk, 932 CLK_RISCV, "riscv", riscv_parents, /* id, name, parents */ 933 0xD00, /* offset */ 934 0, 5, 0, 0, /* m factor */ 935 24, 3, /* mux */ 936 0, /* gate */ 937 AW_CLK_HAS_MUX | AW_CLK_SET_PARENT); /* flags */ 938 939 static const char *riscv_axi_parents[] = { "riscv" }; 940 static struct clk_div_table riscv_axi_div_table[] = { 941 { .value = 1, .divider = 2 }, 942 { .value = 2, .divider = 3 }, 943 { .value = 3, .divider = 4 }, 944 { }, 945 }; 946 DIV_CLK(riscv_axi_clk, 947 CLK_RISCV_AXI, /* id */ 948 "riscv_axi", riscv_axi_parents, /* name, parents */ 949 0xD00, /* offset */ 950 8, 2, /* shift, width */ 951 CLK_DIV_WITH_TABLE, /* flags */ 952 riscv_axi_div_table); /* table */ 953 954 /* TODO FANOUT */ 955 956 static struct aw_ccung_clk ccu_d1_clks[] = { 957 { .type = AW_CLK_NP, .clk.np = &pll_cpux_clk }, 958 { .type = AW_CLK_NMM, .clk.nmm = &pll_ddr0_clk }, 959 { .type = AW_CLK_NMM, .clk.nmm = &pll_periph0_4x_clk }, 960 { .type = AW_CLK_M, .clk.m = &pll_periph0_2x_clk }, 961 { .type = AW_CLK_M, .clk.m = &pll_periph0_800m_clk }, 962 { .type = AW_CLK_FIXED, .clk.fixed = &pll_periph0_clk }, 963 { .type = AW_CLK_NP, .clk.np = &pll_video0_clk }, 964 { .type = AW_CLK_M, .clk.m = &pll_video0_4x_clk }, 965 { .type = AW_CLK_FIXED, .clk.fixed = &pll_video0_2x_clk }, 966 { .type = AW_CLK_NP, .clk.np = &pll_video1_clk }, 967 { .type = AW_CLK_M, .clk.m = &pll_video1_4x_clk }, 968 { .type = AW_CLK_FIXED, .clk.fixed = &pll_video1_2x_clk }, 969 { .type = AW_CLK_NMM, .clk.nmm = &pll_ve_clk }, 970 { .type = AW_CLK_NMM, .clk.nmm = &pll_audio0_4x_clk }, 971 { .type = AW_CLK_FIXED, .clk.fixed = &pll_audio0_2x_clk }, 972 { .type = AW_CLK_FIXED, .clk.fixed = &pll_audio0_clk }, 973 { .type = AW_CLK_NP, .clk.np = &pll_audio1_clk }, 974 { .type = AW_CLK_M, .clk.m = &pll_audio1_div2_clk }, 975 { .type = AW_CLK_M, .clk.m = &pll_audio1_div5_clk }, 976 { .type = AW_CLK_M, .clk.m = &cpux_clk }, 977 { .type = AW_CLK_M, .clk.m = &cpux_axi_clk }, 978 { .type = AW_CLK_M, .clk.m = &cpux_apb_clk }, 979 { .type = AW_CLK_NM, .clk.nm = &psi_ahb_clk }, 980 { .type = AW_CLK_NM, .clk.nm = &apb0_clk }, 981 { .type = AW_CLK_NM, .clk.nm = &apb1_clk }, 982 { .type = AW_CLK_FIXED, .clk.fixed = &mbus_clk }, 983 { .type = AW_CLK_M, .clk.m = &de_clk }, 984 { .type = AW_CLK_M, .clk.m = &di_clk }, 985 { .type = AW_CLK_M, .clk.m = &g2d_clk }, 986 { .type = AW_CLK_NM, .clk.nm = &ce_clk }, 987 { .type = AW_CLK_M, .clk.m = &ve_clk }, 988 { .type = AW_CLK_NM, .clk.nm = &dram_clk }, 989 { .type = AW_CLK_NM, .clk.nm = &mmc0_clk }, 990 { .type = AW_CLK_NM, .clk.nm = &mmc1_clk }, 991 { .type = AW_CLK_NM, .clk.nm = &mmc2_clk }, 992 { .type = AW_CLK_NM, .clk.nm = &spi0_clk }, 993 { .type = AW_CLK_NM, .clk.nm = &spi1_clk }, 994 { .type = AW_CLK_M, .clk.m = &emac_25m_clk }, 995 { .type = AW_CLK_NM, .clk.nm = &irtx_clk }, 996 { .type = AW_CLK_NM, .clk.nm = &i2s0_clk }, 997 { .type = AW_CLK_NM, .clk.nm = &i2s1_clk }, 998 { .type = AW_CLK_NM, .clk.nm = &i2s2_clk }, 999 { .type = AW_CLK_NM, .clk.nm = &i2s2_asrc_clk }, 1000 { .type = AW_CLK_NM, .clk.nm = &spdif_tx_clk }, 1001 { .type = AW_CLK_NM, .clk.nm = &spdif_rx_clk }, 1002 { .type = AW_CLK_NM, .clk.nm = &dmic_clk }, 1003 { .type = AW_CLK_NM, .clk.nm = &audio_dac_clk }, 1004 { .type = AW_CLK_NM, .clk.nm = &audio_adc_clk }, 1005 { .type = AW_CLK_M, .clk.m = &usb_ohci0_clk }, 1006 { .type = AW_CLK_M, .clk.m = &usb_ohci1_clk }, 1007 { .type = AW_CLK_M, .clk.m = &dsi_clk }, 1008 { .type = AW_CLK_NM, .clk.nm = &tconlcd_clk }, 1009 { .type = AW_CLK_NM, .clk.nm = &tcontv_clk }, 1010 { .type = AW_CLK_NM, .clk.nm = &tve_clk }, 1011 { .type = AW_CLK_M, .clk.m = &tvd_clk }, 1012 { .type = AW_CLK_NM, .clk.nm = &ledc_clk }, 1013 { .type = AW_CLK_M, .clk.m = &csi_top_clk }, 1014 { .type = AW_CLK_M, .clk.m = &csi_mclk }, 1015 { .type = AW_CLK_M, .clk.m = &tpadc_clk }, 1016 { .type = AW_CLK_M, .clk.m = &dsp_clk }, 1017 { .type = AW_CLK_M, .clk.m = &riscv_clk }, 1018 { .type = AW_CLK_DIV, .clk.div = &riscv_axi_clk}, 1019 }; 1020 1021 static int 1022 ccu_d1_probe(device_t dev) 1023 { 1024 if (!ofw_bus_status_okay(dev)) 1025 return (ENXIO); 1026 1027 if (!ofw_bus_is_compatible(dev, "allwinner,sun20i-d1-ccu")) 1028 return (ENXIO); 1029 1030 device_set_desc(dev, "Allwinner D1 Clock Controller Unit"); 1031 return (BUS_PROBE_DEFAULT); 1032 } 1033 1034 static int 1035 ccu_d1_attach(device_t dev) 1036 { 1037 struct aw_ccung_softc *sc; 1038 1039 sc = device_get_softc(dev); 1040 1041 sc->resets = ccu_d1_resets; 1042 sc->nresets = nitems(ccu_d1_resets); 1043 sc->gates = ccu_d1_gates; 1044 sc->ngates = nitems(ccu_d1_gates); 1045 sc->clks = ccu_d1_clks; 1046 sc->nclks = nitems(ccu_d1_clks); 1047 1048 return (aw_ccung_attach(dev)); 1049 } 1050 1051 static device_method_t ccu_d1_methods[] = { 1052 DEVMETHOD(device_probe, ccu_d1_probe), 1053 DEVMETHOD(device_attach, ccu_d1_attach), 1054 1055 DEVMETHOD_END 1056 }; 1057 1058 DEFINE_CLASS_1(ccu_d1, ccu_d1_driver, ccu_d1_methods, 1059 sizeof(struct aw_ccung_softc), aw_ccung_driver); 1060 1061 EARLY_DRIVER_MODULE(ccu_d1, simplebus, ccu_d1_driver, 0, 0, 1062 BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); 1063