1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com> 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/io.h> 8 #include <linux/module.h> 9 #include <linux/of_address.h> 10 #include <linux/platform_device.h> 11 12 #include "ccu_common.h" 13 #include "ccu_reset.h" 14 15 #include "ccu_div.h" 16 #include "ccu_gate.h" 17 #include "ccu_mp.h" 18 #include "ccu_mult.h" 19 #include "ccu_nk.h" 20 #include "ccu_nkm.h" 21 #include "ccu_nkmp.h" 22 #include "ccu_nm.h" 23 24 #include "ccu-sun50i-a100.h" 25 26 #define SUN50I_A100_PLL_SDM_ENABLE BIT(24) 27 #define SUN50I_A100_PLL_OUTPUT_ENABLE BIT(27) 28 #define SUN50I_A100_PLL_LOCK BIT(28) 29 #define SUN50I_A100_PLL_LOCK_ENABLE BIT(29) 30 #define SUN50I_A100_PLL_ENABLE BIT(31) 31 32 #define SUN50I_A100_PLL_PERIPH1_PATTERN0 0xd1303333 33 34 /* 35 * The CPU PLL is actually NP clock, with P being /1, /2 or /4. However 36 * P should only be used for output frequencies lower than 288 MHz. 37 * 38 * For now we can just model it as a multiplier clock, and force P to /1. 39 * 40 * The M factor is present in the register's description, but not in the 41 * frequency formula, and it's documented as "M is only used for backdoor 42 * testing", so it's not modelled and then force to 0. 43 */ 44 #define SUN50I_A100_PLL_CPUX_REG 0x000 45 static struct ccu_mult pll_cpux_clk = { 46 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 47 .lock = SUN50I_A100_PLL_LOCK, 48 .mult = _SUNXI_CCU_MULT_MIN(8, 8, 12), 49 .common = { 50 .reg = 0x000, 51 .hw.init = CLK_HW_INIT("pll-cpux", "dcxo24M", 52 &ccu_mult_ops, 53 CLK_SET_RATE_UNGATE), 54 }, 55 }; 56 57 /* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */ 58 #define SUN50I_A100_PLL_DDR0_REG 0x010 59 static struct ccu_nkmp pll_ddr0_clk = { 60 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 61 .lock = SUN50I_A100_PLL_LOCK, 62 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 63 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 64 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ 65 .common = { 66 .reg = 0x010, 67 .hw.init = CLK_HW_INIT("pll-ddr0", "dcxo24M", 68 &ccu_nkmp_ops, 69 CLK_SET_RATE_UNGATE | 70 CLK_IS_CRITICAL), 71 }, 72 }; 73 74 #define SUN50I_A100_PLL_PERIPH0_REG 0x020 75 static struct ccu_nkmp pll_periph0_clk = { 76 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 77 .lock = SUN50I_A100_PLL_LOCK, 78 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 79 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 80 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ 81 .fixed_post_div = 2, 82 .common = { 83 .reg = 0x020, 84 .features = CCU_FEATURE_FIXED_POSTDIV, 85 .hw.init = CLK_HW_INIT("pll-periph0", "dcxo24M", 86 &ccu_nkmp_ops, 87 CLK_SET_RATE_UNGATE), 88 }, 89 }; 90 91 #define SUN50I_A100_PLL_PERIPH1_REG 0x028 92 static struct ccu_nkmp pll_periph1_clk = { 93 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 94 .lock = SUN50I_A100_PLL_LOCK, 95 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 96 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 97 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ 98 .fixed_post_div = 2, 99 .common = { 100 .reg = 0x028, 101 .features = CCU_FEATURE_FIXED_POSTDIV, 102 .hw.init = CLK_HW_INIT("pll-periph1", "dcxo24M", 103 &ccu_nkmp_ops, 104 CLK_SET_RATE_UNGATE), 105 }, 106 }; 107 #define SUN50I_A100_PLL_PERIPH1_PATTERN0_REG 0x128 108 109 #define SUN50I_A100_PLL_GPU_REG 0x030 110 static struct ccu_nkmp pll_gpu_clk = { 111 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 112 .lock = SUN50I_A100_PLL_LOCK, 113 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 114 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 115 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ 116 .common = { 117 .reg = 0x030, 118 .hw.init = CLK_HW_INIT("pll-gpu", "dcxo24M", 119 &ccu_nkmp_ops, 120 CLK_SET_RATE_UNGATE), 121 }, 122 }; 123 124 /* 125 * For Video PLLs, the output divider is described as "used for testing" 126 * in the user manual. So it's not modelled and forced to 0. 127 */ 128 #define SUN50I_A100_PLL_VIDEO0_REG 0x040 129 static struct ccu_nm pll_video0_clk = { 130 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 131 .lock = SUN50I_A100_PLL_LOCK, 132 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 133 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 134 .fixed_post_div = 4, 135 .common = { 136 .reg = 0x040, 137 .features = CCU_FEATURE_FIXED_POSTDIV, 138 .hw.init = CLK_HW_INIT("pll-video0", "dcxo24M", 139 &ccu_nm_ops, 140 CLK_SET_RATE_UNGATE), 141 }, 142 }; 143 144 #define SUN50I_A100_PLL_VIDEO1_REG 0x048 145 static struct ccu_nm pll_video1_clk = { 146 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 147 .lock = SUN50I_A100_PLL_LOCK, 148 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 149 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 150 .fixed_post_div = 4, 151 .common = { 152 .reg = 0x048, 153 .features = CCU_FEATURE_FIXED_POSTDIV, 154 .hw.init = CLK_HW_INIT("pll-video1", "dcxo24M", 155 &ccu_nm_ops, 156 CLK_SET_RATE_UNGATE), 157 }, 158 }; 159 160 #define SUN50I_A100_PLL_VIDEO2_REG 0x050 161 static struct ccu_nm pll_video2_clk = { 162 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 163 .lock = SUN50I_A100_PLL_LOCK, 164 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 165 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 166 .fixed_post_div = 4, 167 .common = { 168 .reg = 0x050, 169 .features = CCU_FEATURE_FIXED_POSTDIV, 170 .hw.init = CLK_HW_INIT("pll-video2", "dcxo24M", 171 &ccu_nm_ops, 172 CLK_SET_RATE_UNGATE), 173 }, 174 }; 175 176 #define SUN50I_A100_PLL_VE_REG 0x058 177 static struct ccu_nkmp pll_ve_clk = { 178 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 179 .lock = SUN50I_A100_PLL_LOCK, 180 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 181 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 182 .p = _SUNXI_CCU_DIV(0, 1), /* output divider */ 183 .common = { 184 .reg = 0x058, 185 .hw.init = CLK_HW_INIT("pll-ve", "dcxo24M", 186 &ccu_nkmp_ops, 187 CLK_SET_RATE_UNGATE), 188 }, 189 }; 190 191 /* 192 * The COM PLL has m0 dividers in addition to the usual N, M 193 * factors. Since we only need 1 frequencies from this PLL: 45.1584 MHz, 194 * ignore it for now. 195 */ 196 #define SUN50I_A100_PLL_COM_REG 0x060 197 static struct ccu_sdm_setting pll_com_sdm_table[] = { 198 { .rate = 451584000, .pattern = 0xc0014396, .m = 2, .n = 37 }, 199 }; 200 201 static struct ccu_nm pll_com_clk = { 202 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 203 .lock = SUN50I_A100_PLL_LOCK, 204 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 205 .m = _SUNXI_CCU_DIV(0, 1), 206 .sdm = _SUNXI_CCU_SDM(pll_com_sdm_table, BIT(24), 207 0x160, BIT(31)), 208 .common = { 209 .reg = 0x060, 210 .features = CCU_FEATURE_SIGMA_DELTA_MOD, 211 .hw.init = CLK_HW_INIT("pll-com", "dcxo24M", 212 &ccu_nm_ops, 213 CLK_SET_RATE_UNGATE), 214 }, 215 }; 216 217 #define SUN50I_A100_PLL_VIDEO3_REG 0x068 218 static struct ccu_nm pll_video3_clk = { 219 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 220 .lock = SUN50I_A100_PLL_LOCK, 221 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 222 .m = _SUNXI_CCU_DIV(1, 1), /* input divider */ 223 .fixed_post_div = 4, 224 .common = { 225 .reg = 0x068, 226 .features = CCU_FEATURE_FIXED_POSTDIV, 227 .hw.init = CLK_HW_INIT("pll-video3", "dcxo24M", 228 &ccu_nm_ops, 229 CLK_SET_RATE_UNGATE), 230 }, 231 }; 232 233 /* 234 * The Audio PLL has m0, m1 dividers in addition to the usual N, M 235 * factors. Since we only need 4 frequencies from this PLL: 22.5792 MHz, 236 * 24.576 MHz, 90.3168MHz and 98.304MHz ignore them for now. 237 * Enforce the default for them, which is m0 = 1, m1 = 0. 238 */ 239 #define SUN50I_A100_PLL_AUDIO_REG 0x078 240 static struct ccu_sdm_setting pll_audio_sdm_table[] = { 241 { .rate = 45158400, .pattern = 0xc001bcd3, .m = 18, .n = 33 }, 242 { .rate = 49152000, .pattern = 0xc001eb85, .m = 20, .n = 40 }, 243 { .rate = 180633600, .pattern = 0xc001288d, .m = 3, .n = 22 }, 244 { .rate = 196608000, .pattern = 0xc001eb85, .m = 5, .n = 40 }, 245 }; 246 247 static struct ccu_nm pll_audio_clk = { 248 .enable = SUN50I_A100_PLL_OUTPUT_ENABLE, 249 .lock = SUN50I_A100_PLL_LOCK, 250 .n = _SUNXI_CCU_MULT_MIN(8, 8, 12), 251 .m = _SUNXI_CCU_DIV(16, 6), 252 .fixed_post_div = 2, 253 .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, BIT(24), 254 0x178, BIT(31)), 255 .common = { 256 .reg = 0x078, 257 .features = CCU_FEATURE_FIXED_POSTDIV | 258 CCU_FEATURE_SIGMA_DELTA_MOD, 259 .hw.init = CLK_HW_INIT("pll-audio", "dcxo24M", 260 &ccu_nm_ops, 261 CLK_SET_RATE_UNGATE), 262 }, 263 }; 264 265 static const char * const cpux_parents[] = { "dcxo24M", "osc32k", 266 "iosc", "pll-cpux", 267 "pll-periph0" }; 268 static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, 269 0x500, 24, 3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 270 static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x500, 0, 2, 0); 271 static SUNXI_CCU_M(cpux_apb_clk, "cpux-apb", "cpux", 0x500, 8, 2, 0); 272 273 static const char * const psi_ahb1_ahb2_parents[] = { "dcxo24M", "osc32k", 274 "iosc", "pll-periph0", 275 "pll-periph0-2x" }; 276 static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2", 277 psi_ahb1_ahb2_parents, 0x510, 278 0, 2, /* M */ 279 8, 2, /* P */ 280 24, 3, /* mux */ 281 0); 282 283 static const char * const ahb3_apb1_apb2_parents[] = { "dcxo24M", "osc32k", 284 "psi-ahb1-ahb2", 285 "pll-periph0", 286 "pll-periph0-2x" }; 287 static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, 288 0, 2, /* M */ 289 8, 2, /* P */ 290 24, 3, /* mux */ 291 0); 292 293 static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, 294 0, 2, /* M */ 295 8, 2, /* P */ 296 24, 3, /* mux */ 297 0); 298 299 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, 300 0, 2, /* M */ 301 8, 2, /* P */ 302 24, 3, /* mux */ 303 0); 304 305 static const char * const mbus_parents[] = { "dcxo24M", "pll-ddr0", 306 "pll-periph0", 307 "pll-periph0-2x" }; 308 static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x540, 309 0, 3, /* M */ 310 24, 2, /* mux */ 311 BIT(31), /* gate */ 312 CLK_IS_CRITICAL); 313 314 static const char * const de_parents[] = { "pll-com", "pll-periph0-2x" }; 315 static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de0", de_parents, 0x600, 316 0, 4, /* M */ 317 24, 1, /* mux */ 318 BIT(31), /* gate */ 319 CLK_SET_RATE_PARENT); 320 321 static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "psi-ahb1-ahb2", 322 0x60c, BIT(0), 0); 323 324 static const char * const g2d_parents[] = { "pll-com", "pll-periph0-2x", 325 "pll-video0-2x", "pll-video1-2x", 326 "pll-video2-2x"}; 327 static SUNXI_CCU_M_WITH_MUX_GATE(g2d_clk, "g2d", 328 g2d_parents, 329 0x630, 330 0, 4, /* M */ 331 24, 3, /* mux */ 332 BIT(31), /* gate */ 333 0); 334 335 static SUNXI_CCU_GATE(bus_g2d_clk, "bus-g2d", "psi-ahb1-ahb2", 336 0x63c, BIT(0), 0); 337 338 static const char * const gpu_parents[] = { "pll-gpu" }; 339 static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670, 340 0, 2, /* M */ 341 24, 1, /* mux */ 342 BIT(31), /* gate */ 343 0); 344 345 static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2", 346 0x67c, BIT(0), 0); 347 348 static const char * const ce_parents[] = { "dcxo24M", "pll-periph0-2x" }; 349 static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680, 350 0, 4, /* M */ 351 8, 2, /* P */ 352 24, 1, /* mux */ 353 BIT(31), /* gate */ 354 0); 355 356 static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "psi-ahb1-ahb2", 357 0x68c, BIT(0), 0); 358 359 static const char * const ve_parents[] = { "pll-ve" }; 360 static SUNXI_CCU_M_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690, 361 0, 3, /* M */ 362 24, 1, /* mux */ 363 BIT(31), /* gate */ 364 CLK_SET_RATE_PARENT); 365 366 static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "psi-ahb1-ahb2", 367 0x69c, BIT(0), 0); 368 369 static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "psi-ahb1-ahb2", 370 0x70c, BIT(0), 0); 371 372 static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "psi-ahb1-ahb2", 373 0x71c, BIT(0), 0); 374 375 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "psi-ahb1-ahb2", 376 0x72c, BIT(0), 0); 377 378 static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "psi-ahb1-ahb2", 379 0x73c, BIT(0), 0); 380 381 static SUNXI_CCU_GATE(avs_clk, "avs", "dcxo24M", 0x740, BIT(31), 0); 382 383 static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2", 384 0x78c, BIT(0), 0); 385 386 static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2", 387 0x79c, BIT(0), 0); 388 389 static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0); 390 391 static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0); 392 393 static SUNXI_CCU_GATE(mbus_dma_clk, "mbus-dma", "mbus", 394 0x804, BIT(0), 0); 395 static SUNXI_CCU_GATE(mbus_ve_clk, "mbus-ve", "mbus", 396 0x804, BIT(1), 0); 397 static SUNXI_CCU_GATE(mbus_ce_clk, "mbus-ce", "mbus", 398 0x804, BIT(2), 0); 399 static SUNXI_CCU_GATE(mbus_nand_clk, "mbus-nand", "mbus", 400 0x804, BIT(5), 0); 401 static SUNXI_CCU_GATE(mbus_csi_clk, "mbus-csi", "mbus", 402 0x804, BIT(8), 0); 403 static SUNXI_CCU_GATE(mbus_isp_clk, "mbus-isp", "mbus", 404 0x804, BIT(9), 0); 405 static SUNXI_CCU_GATE(mbus_g2d_clk, "mbus-g2d", "mbus", 406 0x804, BIT(10), 0); 407 408 static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "psi-ahb1-ahb2", 409 0x80c, BIT(0), CLK_IS_CRITICAL); 410 411 static const char * const nand_spi_parents[] = { "dcxo24M", 412 "pll-periph0", 413 "pll-periph1", 414 "pll-periph0-2x", 415 "pll-periph1-2x" }; 416 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", nand_spi_parents, 0x810, 417 0, 4, /* M */ 418 8, 2, /* P */ 419 24, 3, /* mux */ 420 BIT(31), /* gate */ 421 0); 422 423 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", nand_spi_parents, 0x814, 424 0, 4, /* M */ 425 8, 2, /* P */ 426 24, 3, /* mux */ 427 BIT(31), /* gate */ 428 0); 429 430 static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0); 431 432 static const char * const mmc_parents[] = { "dcxo24M", "pll-periph0-2x", 433 "pll-periph1-2x" }; 434 static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830, 435 0, 4, /* M */ 436 8, 2, /* P */ 437 24, 2, /* mux */ 438 BIT(31), /* gate */ 439 2, /* post-div */ 440 CLK_SET_RATE_NO_REPARENT); 441 442 static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, 443 0, 4, /* M */ 444 8, 2, /* P */ 445 24, 2, /* mux */ 446 BIT(31), /* gate */ 447 2, /* post-div */ 448 CLK_SET_RATE_NO_REPARENT); 449 450 static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, 451 0, 4, /* M */ 452 8, 2, /* P */ 453 24, 2, /* mux */ 454 BIT(31), /* gate */ 455 2, /* post-div */ 456 CLK_SET_RATE_NO_REPARENT); 457 458 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); 459 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); 460 static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb3", 0x84c, BIT(2), 0); 461 462 static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 0x90c, BIT(0), 0); 463 static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 0x90c, BIT(1), 0); 464 static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 0x90c, BIT(2), 0); 465 static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 0x90c, BIT(3), 0); 466 static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 0x90c, BIT(4), 0); 467 468 static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 0x91c, BIT(0), 0); 469 static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 0x91c, BIT(1), 0); 470 static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 0x91c, BIT(2), 0); 471 static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", 0x91c, BIT(3), 0); 472 473 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", nand_spi_parents, 0x940, 474 0, 4, /* M */ 475 8, 2, /* P */ 476 24, 3, /* mux */ 477 BIT(31), /* gate */ 478 0); 479 480 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", nand_spi_parents, 0x944, 481 0, 4, /* M */ 482 8, 2, /* P */ 483 24, 3, /* mux */ 484 BIT(31), /* gate */ 485 0); 486 487 static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", nand_spi_parents, 0x948, 488 0, 4, /* M */ 489 8, 2, /* P */ 490 24, 3, /* mux */ 491 BIT(31), /* gate */ 492 0); 493 494 static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb3", 0x96c, BIT(0), 0); 495 static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb3", 0x96c, BIT(1), 0); 496 static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb3", 0x96c, BIT(2), 0); 497 498 static SUNXI_CCU_GATE(emac_25m_clk, "emac-25m", "ahb3", 0x970, 499 BIT(31) | BIT(30), 0); 500 501 static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb3", 0x97c, BIT(0), 0); 502 503 static const char * const ir_parents[] = { "osc32k", "iosc", 504 "pll-periph0", "pll-periph1" }; 505 static SUNXI_CCU_MP_WITH_MUX_GATE(ir_rx_clk, "ir-rx", ir_parents, 0x990, 506 0, 4, /* M */ 507 8, 2, /* P */ 508 24, 3, /* mux */ 509 BIT(31), /* gate */ 510 0); 511 512 static SUNXI_CCU_GATE(bus_ir_rx_clk, "bus-ir-rx", "ahb3", 0x99c, BIT(0), 0); 513 514 static SUNXI_CCU_MP_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_parents, 0x9c0, 515 0, 4, /* M */ 516 8, 2, /* P */ 517 24, 3, /* mux */ 518 BIT(31), /* gate */ 519 0); 520 521 static SUNXI_CCU_GATE(bus_ir_tx_clk, "bus-ir-tx", "apb1", 0x9cc, BIT(0), 0); 522 523 static SUNXI_CCU_GATE(bus_gpadc_clk, "bus-gpadc", "apb1", 0x9ec, BIT(0), 0); 524 525 static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 0x9fc, BIT(0), 0); 526 527 static const char * const audio_parents[] = { "pll-audio", "pll-com-audio" }; 528 static struct ccu_div i2s0_clk = { 529 .enable = BIT(31), 530 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), 531 .mux = _SUNXI_CCU_MUX(24, 2), 532 .common = { 533 .reg = 0xa10, 534 .hw.init = CLK_HW_INIT_PARENTS("i2s0", 535 audio_parents, 536 &ccu_div_ops, 537 CLK_SET_RATE_PARENT), 538 }, 539 }; 540 541 static struct ccu_div i2s1_clk = { 542 .enable = BIT(31), 543 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), 544 .mux = _SUNXI_CCU_MUX(24, 2), 545 .common = { 546 .reg = 0xa14, 547 .hw.init = CLK_HW_INIT_PARENTS("i2s1", 548 audio_parents, 549 &ccu_div_ops, 550 CLK_SET_RATE_PARENT), 551 }, 552 }; 553 554 static struct ccu_div i2s2_clk = { 555 .enable = BIT(31), 556 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), 557 .mux = _SUNXI_CCU_MUX(24, 2), 558 .common = { 559 .reg = 0xa18, 560 .hw.init = CLK_HW_INIT_PARENTS("i2s2", 561 audio_parents, 562 &ccu_div_ops, 563 CLK_SET_RATE_PARENT), 564 }, 565 }; 566 567 static struct ccu_div i2s3_clk = { 568 .enable = BIT(31), 569 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), 570 .mux = _SUNXI_CCU_MUX(24, 2), 571 .common = { 572 .reg = 0xa1c, 573 .hw.init = CLK_HW_INIT_PARENTS("i2s3", 574 audio_parents, 575 &ccu_div_ops, 576 CLK_SET_RATE_PARENT), 577 }, 578 }; 579 580 static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 0xa20, BIT(0), 0); 581 static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 0xa20, BIT(1), 0); 582 static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", 0xa20, BIT(2), 0); 583 static SUNXI_CCU_GATE(bus_i2s3_clk, "bus-i2s3", "apb1", 0xa20, BIT(3), 0); 584 585 static struct ccu_div spdif_clk = { 586 .enable = BIT(31), 587 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), 588 .mux = _SUNXI_CCU_MUX(24, 2), 589 .common = { 590 .reg = 0xa24, 591 .hw.init = CLK_HW_INIT_PARENTS("spdif", 592 audio_parents, 593 &ccu_div_ops, 594 0), 595 }, 596 }; 597 598 static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 0xa2c, BIT(0), 0); 599 600 static struct ccu_div dmic_clk = { 601 .enable = BIT(31), 602 .div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO), 603 .mux = _SUNXI_CCU_MUX(24, 2), 604 .common = { 605 .reg = 0xa40, 606 .hw.init = CLK_HW_INIT_PARENTS("dmic", 607 audio_parents, 608 &ccu_div_ops, 609 0), 610 }, 611 }; 612 613 static SUNXI_CCU_GATE(bus_dmic_clk, "bus-dmic", "apb1", 0xa4c, BIT(0), 0); 614 615 static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_dac_clk, "audio-codec-dac", 616 audio_parents, 0xa50, 617 0, 4, /* M */ 618 24, 2, /* mux */ 619 BIT(31), /* gate */ 620 0); 621 622 static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_adc_clk, "audio-codec-adc", 623 audio_parents, 0xa54, 624 0, 4, /* M */ 625 24, 2, /* mux */ 626 BIT(31), /* gate */ 627 0); 628 629 static SUNXI_CCU_M_WITH_MUX_GATE(audio_codec_4x_clk, "audio-codec-4x", 630 audio_parents, 0xa58, 631 0, 4, /* M */ 632 24, 2, /* mux */ 633 BIT(31), /* gate */ 634 0); 635 636 static SUNXI_CCU_GATE(bus_audio_codec_clk, "bus-audio-codec", "apb1", 0xa5c, 637 BIT(0), 0); 638 639 /* 640 * There are OHCI 12M clock source selection bits for 2 USB 2.0 ports. 641 * We will force them to 0 (12M divided from 48M). 642 */ 643 #define SUN50I_A100_USB0_CLK_REG 0xa70 644 #define SUN50I_A100_USB1_CLK_REG 0xa74 645 646 static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 0xa70, BIT(31), 0); 647 static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "dcxo24M", 0xa70, BIT(29), 0); 648 649 static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 0xa74, BIT(31), 0); 650 static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "dcxo24M", 0xa74, BIT(29), 0); 651 652 static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb3", 0xa8c, BIT(0), 0); 653 static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb3", 0xa8c, BIT(1), 0); 654 static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb3", 0xa8c, BIT(4), 0); 655 static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb3", 0xa8c, BIT(5), 0); 656 static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb3", 0xa8c, BIT(8), 0); 657 658 static SUNXI_CCU_GATE(bus_lradc_clk, "bus-lradc", "ahb3", 0xa9c, BIT(0), 0); 659 660 static SUNXI_CCU_GATE(bus_dpss_top0_clk, "bus-dpss-top0", "ahb3", 661 0xabc, BIT(0), 0); 662 663 static SUNXI_CCU_GATE(bus_dpss_top1_clk, "bus-dpss-top1", "ahb3", 664 0xacc, BIT(0), 0); 665 666 static const char * const mipi_dsi_parents[] = { "dcxo24M", "pll-periph0-2x", 667 "pll-periph0" }; 668 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", 669 mipi_dsi_parents, 670 0xb24, 671 0, 4, /* M */ 672 24, 2, /* mux */ 673 BIT(31), /* gate */ 674 0); 675 676 static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb3", 677 0xb4c, BIT(0), 0); 678 679 static const char * const tcon_lcd_parents[] = { "pll-video0-4x", 680 "pll-video1-4x", 681 "pll-video2-4x", 682 "pll-video3-4x", 683 "pll-periph0-2x" }; 684 static SUNXI_CCU_MP_WITH_MUX_GATE(tcon_lcd_clk, "tcon-lcd0", 685 tcon_lcd_parents, 0xb60, 686 0, 4, /* M */ 687 8, 2, /* P */ 688 24, 3, /* mux */ 689 BIT(31), /* gate */ 690 0); 691 692 static SUNXI_CCU_GATE(bus_tcon_lcd_clk, "bus-tcon-lcd0", "ahb3", 693 0xb7c, BIT(0), 0); 694 695 static const char * const ledc_parents[] = { "dcxo24M", 696 "pll-periph0" }; 697 static SUNXI_CCU_MP_WITH_MUX_GATE(ledc_clk, "ledc", 698 ledc_parents, 0xbf0, 699 0, 4, /* M */ 700 8, 2, /* P */ 701 24, 3, /* mux */ 702 BIT(31), /* gate */ 703 0); 704 705 static SUNXI_CCU_GATE(bus_ledc_clk, "bus-ledc", "ahb3", 0xbfc, BIT(0), 0); 706 707 static const char * const csi_top_parents[] = { "pll-periph0-2x", 708 "pll-video0-2x", 709 "pll-video1-2x", 710 "pll-video2-2x", 711 "pll-video3-2x" }; 712 static SUNXI_CCU_M_WITH_MUX_GATE(csi_top_clk, "csi-top", 713 csi_top_parents, 0xc04, 714 0, 4, /* M */ 715 24, 3, /* mux */ 716 BIT(31), /* gate */ 717 0); 718 719 static const char * const csi0_mclk_parents[] = { "dcxo24M", "pll-video2", 720 "pll-video3", "pll-video0", 721 "pll-video1" }; 722 static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", 723 csi0_mclk_parents, 0xc08, 724 0, 5, /* M */ 725 24, 3, /* mux */ 726 BIT(31), /* gate */ 727 0); 728 729 static const char * const csi1_mclk_parents[] = { "dcxo24M", "pll-video3", 730 "pll-video0", "pll-video1", 731 "pll-video2" }; 732 static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk", 733 csi1_mclk_parents, 0xc0c, 734 0, 5, /* M */ 735 24, 3, /* mux */ 736 BIT(31), /* gate */ 737 0); 738 739 static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb3", 0xc1c, BIT(0), 0); 740 741 static const char * const csi_isp_parents[] = { "pll-periph0-2x", 742 "pll-video0-2x", 743 "pll-video1-2x", 744 "pll-video2-2x", 745 "pll-video3-2x" }; 746 static SUNXI_CCU_M_WITH_MUX_GATE(csi_isp_clk, "csi-isp", 747 csi_isp_parents, 0xc20, 748 0, 5, /* M */ 749 24, 3, /* mux */ 750 BIT(31), /* gate */ 751 0); 752 753 /* Fixed factor clocks */ 754 static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0); 755 756 static CLK_FIXED_FACTOR_HW(pll_com_audio_clk, "pll-com-audio", 757 &pll_com_clk.common.hw, 758 5, 1, CLK_SET_RATE_PARENT); 759 760 static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x", 761 &pll_periph0_clk.common.hw, 762 1, 2, 0); 763 764 static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x", 765 &pll_periph1_clk.common.hw, 766 1, 2, 0); 767 768 static const struct clk_hw *pll_video0_parents[] = { 769 &pll_video0_clk.common.hw 770 }; 771 static CLK_FIXED_FACTOR_HWS(pll_video0_4x_clk, "pll-video0-4x", 772 pll_video0_parents, 773 1, 4, CLK_SET_RATE_PARENT); 774 static CLK_FIXED_FACTOR_HWS(pll_video0_2x_clk, "pll-video0-2x", 775 pll_video0_parents, 776 1, 2, CLK_SET_RATE_PARENT); 777 778 static const struct clk_hw *pll_video1_parents[] = { 779 &pll_video1_clk.common.hw 780 }; 781 static CLK_FIXED_FACTOR_HWS(pll_video1_4x_clk, "pll-video1-4x", 782 pll_video1_parents, 783 1, 4, CLK_SET_RATE_PARENT); 784 static CLK_FIXED_FACTOR_HWS(pll_video1_2x_clk, "pll-video1-2x", 785 pll_video1_parents, 786 1, 2, CLK_SET_RATE_PARENT); 787 788 static const struct clk_hw *pll_video2_parents[] = { 789 &pll_video2_clk.common.hw 790 }; 791 static CLK_FIXED_FACTOR_HWS(pll_video2_4x_clk, "pll-video2-4x", 792 pll_video2_parents, 793 1, 4, CLK_SET_RATE_PARENT); 794 static CLK_FIXED_FACTOR_HWS(pll_video2_2x_clk, "pll-video2-2x", 795 pll_video2_parents, 796 1, 2, CLK_SET_RATE_PARENT); 797 798 static const struct clk_hw *pll_video3_parents[] = { 799 &pll_video3_clk.common.hw 800 }; 801 static CLK_FIXED_FACTOR_HWS(pll_video3_4x_clk, "pll-video3-4x", 802 pll_video3_parents, 803 1, 4, CLK_SET_RATE_PARENT); 804 static CLK_FIXED_FACTOR_HWS(pll_video3_2x_clk, "pll-video3-2x", 805 pll_video3_parents, 806 1, 2, CLK_SET_RATE_PARENT); 807 808 static struct ccu_common *sun50i_a100_ccu_clks[] = { 809 &pll_cpux_clk.common, 810 &pll_ddr0_clk.common, 811 &pll_periph0_clk.common, 812 &pll_periph1_clk.common, 813 &pll_gpu_clk.common, 814 &pll_video0_clk.common, 815 &pll_video1_clk.common, 816 &pll_video2_clk.common, 817 &pll_video3_clk.common, 818 &pll_ve_clk.common, 819 &pll_com_clk.common, 820 &pll_audio_clk.common, 821 &cpux_clk.common, 822 &axi_clk.common, 823 &cpux_apb_clk.common, 824 &psi_ahb1_ahb2_clk.common, 825 &ahb3_clk.common, 826 &apb1_clk.common, 827 &apb2_clk.common, 828 &mbus_clk.common, 829 &de_clk.common, 830 &bus_de_clk.common, 831 &g2d_clk.common, 832 &bus_g2d_clk.common, 833 &gpu_clk.common, 834 &bus_gpu_clk.common, 835 &ce_clk.common, 836 &bus_ce_clk.common, 837 &ve_clk.common, 838 &bus_ve_clk.common, 839 &bus_dma_clk.common, 840 &bus_msgbox_clk.common, 841 &bus_spinlock_clk.common, 842 &bus_hstimer_clk.common, 843 &avs_clk.common, 844 &bus_dbg_clk.common, 845 &bus_psi_clk.common, 846 &bus_pwm_clk.common, 847 &bus_iommu_clk.common, 848 &mbus_dma_clk.common, 849 &mbus_ve_clk.common, 850 &mbus_ce_clk.common, 851 &mbus_nand_clk.common, 852 &mbus_csi_clk.common, 853 &mbus_isp_clk.common, 854 &mbus_g2d_clk.common, 855 &bus_dram_clk.common, 856 &nand0_clk.common, 857 &nand1_clk.common, 858 &bus_nand_clk.common, 859 &mmc0_clk.common, 860 &mmc1_clk.common, 861 &mmc2_clk.common, 862 &bus_mmc0_clk.common, 863 &bus_mmc1_clk.common, 864 &bus_mmc2_clk.common, 865 &bus_uart0_clk.common, 866 &bus_uart1_clk.common, 867 &bus_uart2_clk.common, 868 &bus_uart3_clk.common, 869 &bus_uart4_clk.common, 870 &bus_i2c0_clk.common, 871 &bus_i2c1_clk.common, 872 &bus_i2c2_clk.common, 873 &bus_i2c3_clk.common, 874 &spi0_clk.common, 875 &spi1_clk.common, 876 &spi2_clk.common, 877 &bus_spi0_clk.common, 878 &bus_spi1_clk.common, 879 &bus_spi2_clk.common, 880 &emac_25m_clk.common, 881 &bus_emac_clk.common, 882 &ir_rx_clk.common, 883 &bus_ir_rx_clk.common, 884 &ir_tx_clk.common, 885 &bus_ir_tx_clk.common, 886 &bus_gpadc_clk.common, 887 &bus_ths_clk.common, 888 &i2s0_clk.common, 889 &i2s1_clk.common, 890 &i2s2_clk.common, 891 &i2s3_clk.common, 892 &bus_i2s0_clk.common, 893 &bus_i2s1_clk.common, 894 &bus_i2s2_clk.common, 895 &bus_i2s3_clk.common, 896 &spdif_clk.common, 897 &bus_spdif_clk.common, 898 &dmic_clk.common, 899 &bus_dmic_clk.common, 900 &audio_codec_dac_clk.common, 901 &audio_codec_adc_clk.common, 902 &audio_codec_4x_clk.common, 903 &bus_audio_codec_clk.common, 904 &usb_ohci0_clk.common, 905 &usb_phy0_clk.common, 906 &usb_ohci1_clk.common, 907 &usb_phy1_clk.common, 908 &bus_ohci0_clk.common, 909 &bus_ohci1_clk.common, 910 &bus_ehci0_clk.common, 911 &bus_ehci1_clk.common, 912 &bus_otg_clk.common, 913 &bus_lradc_clk.common, 914 &bus_dpss_top0_clk.common, 915 &bus_dpss_top1_clk.common, 916 &mipi_dsi_clk.common, 917 &bus_mipi_dsi_clk.common, 918 &tcon_lcd_clk.common, 919 &bus_tcon_lcd_clk.common, 920 &ledc_clk.common, 921 &bus_ledc_clk.common, 922 &csi_top_clk.common, 923 &csi0_mclk_clk.common, 924 &csi1_mclk_clk.common, 925 &bus_csi_clk.common, 926 &csi_isp_clk.common, 927 }; 928 929 static struct clk_hw_onecell_data sun50i_a100_hw_clks = { 930 .hws = { 931 [CLK_OSC12M] = &osc12M_clk.hw, 932 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, 933 [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, 934 [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw, 935 [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw, 936 [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw, 937 [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw, 938 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, 939 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, 940 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, 941 [CLK_PLL_VIDEO0_4X] = &pll_video0_4x_clk.hw, 942 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, 943 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, 944 [CLK_PLL_VIDEO1_4X] = &pll_video1_4x_clk.hw, 945 [CLK_PLL_VIDEO2] = &pll_video2_clk.common.hw, 946 [CLK_PLL_VIDEO2_2X] = &pll_video2_2x_clk.hw, 947 [CLK_PLL_VIDEO2_4X] = &pll_video2_4x_clk.hw, 948 [CLK_PLL_VIDEO3] = &pll_video3_clk.common.hw, 949 [CLK_PLL_VIDEO3_2X] = &pll_video3_2x_clk.hw, 950 [CLK_PLL_VIDEO3_4X] = &pll_video3_4x_clk.hw, 951 [CLK_PLL_VE] = &pll_ve_clk.common.hw, 952 [CLK_PLL_COM] = &pll_com_clk.common.hw, 953 [CLK_PLL_COM_AUDIO] = &pll_com_audio_clk.hw, 954 [CLK_PLL_AUDIO] = &pll_audio_clk.common.hw, 955 [CLK_CPUX] = &cpux_clk.common.hw, 956 [CLK_AXI] = &axi_clk.common.hw, 957 [CLK_CPUX_APB] = &cpux_apb_clk.common.hw, 958 [CLK_PSI_AHB1_AHB2] = &psi_ahb1_ahb2_clk.common.hw, 959 [CLK_AHB3] = &ahb3_clk.common.hw, 960 [CLK_APB1] = &apb1_clk.common.hw, 961 [CLK_APB2] = &apb2_clk.common.hw, 962 [CLK_MBUS] = &mbus_clk.common.hw, 963 [CLK_DE] = &de_clk.common.hw, 964 [CLK_BUS_DE] = &bus_de_clk.common.hw, 965 [CLK_G2D] = &g2d_clk.common.hw, 966 [CLK_BUS_G2D] = &bus_g2d_clk.common.hw, 967 [CLK_GPU] = &gpu_clk.common.hw, 968 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, 969 [CLK_CE] = &ce_clk.common.hw, 970 [CLK_BUS_CE] = &bus_ce_clk.common.hw, 971 [CLK_VE] = &ve_clk.common.hw, 972 [CLK_BUS_VE] = &bus_ve_clk.common.hw, 973 [CLK_BUS_DMA] = &bus_dma_clk.common.hw, 974 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, 975 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, 976 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, 977 [CLK_AVS] = &avs_clk.common.hw, 978 [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, 979 [CLK_BUS_PSI] = &bus_psi_clk.common.hw, 980 [CLK_BUS_PWM] = &bus_pwm_clk.common.hw, 981 [CLK_BUS_IOMMU] = &bus_iommu_clk.common.hw, 982 [CLK_MBUS_DMA] = &mbus_dma_clk.common.hw, 983 [CLK_MBUS_VE] = &mbus_ve_clk.common.hw, 984 [CLK_MBUS_CE] = &mbus_ce_clk.common.hw, 985 [CLK_MBUS_NAND] = &mbus_nand_clk.common.hw, 986 [CLK_MBUS_CSI] = &mbus_csi_clk.common.hw, 987 [CLK_MBUS_ISP] = &mbus_isp_clk.common.hw, 988 [CLK_MBUS_G2D] = &mbus_g2d_clk.common.hw, 989 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, 990 [CLK_NAND0] = &nand0_clk.common.hw, 991 [CLK_NAND1] = &nand1_clk.common.hw, 992 [CLK_BUS_NAND] = &bus_nand_clk.common.hw, 993 [CLK_MMC0] = &mmc0_clk.common.hw, 994 [CLK_MMC1] = &mmc1_clk.common.hw, 995 [CLK_MMC2] = &mmc2_clk.common.hw, 996 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, 997 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, 998 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, 999 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, 1000 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, 1001 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, 1002 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, 1003 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, 1004 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, 1005 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, 1006 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, 1007 [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw, 1008 [CLK_SPI0] = &spi0_clk.common.hw, 1009 [CLK_SPI1] = &spi1_clk.common.hw, 1010 [CLK_SPI2] = &spi2_clk.common.hw, 1011 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, 1012 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, 1013 [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw, 1014 [CLK_EMAC_25M] = &emac_25m_clk.common.hw, 1015 [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, 1016 [CLK_IR_RX] = &ir_rx_clk.common.hw, 1017 [CLK_BUS_IR_RX] = &bus_ir_rx_clk.common.hw, 1018 [CLK_IR_TX] = &ir_tx_clk.common.hw, 1019 [CLK_BUS_IR_TX] = &bus_ir_tx_clk.common.hw, 1020 [CLK_BUS_GPADC] = &bus_gpadc_clk.common.hw, 1021 [CLK_BUS_THS] = &bus_ths_clk.common.hw, 1022 [CLK_I2S0] = &i2s0_clk.common.hw, 1023 [CLK_I2S1] = &i2s1_clk.common.hw, 1024 [CLK_I2S2] = &i2s2_clk.common.hw, 1025 [CLK_I2S3] = &i2s3_clk.common.hw, 1026 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, 1027 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, 1028 [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, 1029 [CLK_BUS_I2S3] = &bus_i2s3_clk.common.hw, 1030 [CLK_SPDIF] = &spdif_clk.common.hw, 1031 [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, 1032 [CLK_DMIC] = &dmic_clk.common.hw, 1033 [CLK_BUS_DMIC] = &bus_dmic_clk.common.hw, 1034 [CLK_AUDIO_DAC] = &audio_codec_dac_clk.common.hw, 1035 [CLK_AUDIO_ADC] = &audio_codec_adc_clk.common.hw, 1036 [CLK_AUDIO_4X] = &audio_codec_4x_clk.common.hw, 1037 [CLK_BUS_AUDIO_CODEC] = &bus_audio_codec_clk.common.hw, 1038 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, 1039 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, 1040 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, 1041 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, 1042 [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, 1043 [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw, 1044 [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, 1045 [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw, 1046 [CLK_BUS_OTG] = &bus_otg_clk.common.hw, 1047 [CLK_BUS_LRADC] = &bus_lradc_clk.common.hw, 1048 [CLK_BUS_DPSS_TOP0] = &bus_dpss_top0_clk.common.hw, 1049 [CLK_BUS_DPSS_TOP1] = &bus_dpss_top1_clk.common.hw, 1050 [CLK_MIPI_DSI] = &mipi_dsi_clk.common.hw, 1051 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, 1052 [CLK_TCON_LCD] = &tcon_lcd_clk.common.hw, 1053 [CLK_BUS_TCON_LCD] = &bus_tcon_lcd_clk.common.hw, 1054 [CLK_LEDC] = &ledc_clk.common.hw, 1055 [CLK_BUS_LEDC] = &bus_ledc_clk.common.hw, 1056 [CLK_CSI_TOP] = &csi_top_clk.common.hw, 1057 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw, 1058 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw, 1059 [CLK_BUS_CSI] = &bus_csi_clk.common.hw, 1060 [CLK_CSI_ISP] = &csi_isp_clk.common.hw, 1061 }, 1062 .num = CLK_NUMBER, 1063 }; 1064 1065 static struct ccu_reset_map sun50i_a100_ccu_resets[] = { 1066 [RST_MBUS] = { 0x540, BIT(30) }, 1067 1068 [RST_BUS_DE] = { 0x60c, BIT(16) }, 1069 [RST_BUS_G2D] = { 0x63c, BIT(16) }, 1070 [RST_BUS_GPU] = { 0x67c, BIT(16) }, 1071 [RST_BUS_CE] = { 0x68c, BIT(16) }, 1072 [RST_BUS_VE] = { 0x69c, BIT(16) }, 1073 [RST_BUS_DMA] = { 0x70c, BIT(16) }, 1074 [RST_BUS_MSGBOX] = { 0x71c, BIT(16) }, 1075 [RST_BUS_SPINLOCK] = { 0x72c, BIT(16) }, 1076 [RST_BUS_HSTIMER] = { 0x73c, BIT(16) }, 1077 [RST_BUS_DBG] = { 0x78c, BIT(16) }, 1078 [RST_BUS_PSI] = { 0x79c, BIT(16) }, 1079 [RST_BUS_PWM] = { 0x7ac, BIT(16) }, 1080 [RST_BUS_DRAM] = { 0x80c, BIT(16) }, 1081 [RST_BUS_NAND] = { 0x82c, BIT(16) }, 1082 [RST_BUS_MMC0] = { 0x84c, BIT(16) }, 1083 [RST_BUS_MMC1] = { 0x84c, BIT(17) }, 1084 [RST_BUS_MMC2] = { 0x84c, BIT(18) }, 1085 [RST_BUS_UART0] = { 0x90c, BIT(16) }, 1086 [RST_BUS_UART1] = { 0x90c, BIT(17) }, 1087 [RST_BUS_UART2] = { 0x90c, BIT(18) }, 1088 [RST_BUS_UART3] = { 0x90c, BIT(19) }, 1089 [RST_BUS_UART4] = { 0x90c, BIT(20) }, 1090 [RST_BUS_I2C0] = { 0x91c, BIT(16) }, 1091 [RST_BUS_I2C1] = { 0x91c, BIT(17) }, 1092 [RST_BUS_I2C2] = { 0x91c, BIT(18) }, 1093 [RST_BUS_I2C3] = { 0x91c, BIT(19) }, 1094 [RST_BUS_SPI0] = { 0x96c, BIT(16) }, 1095 [RST_BUS_SPI1] = { 0x96c, BIT(17) }, 1096 [RST_BUS_SPI2] = { 0x96c, BIT(18) }, 1097 [RST_BUS_EMAC] = { 0x97c, BIT(16) }, 1098 [RST_BUS_IR_RX] = { 0x99c, BIT(16) }, 1099 [RST_BUS_IR_TX] = { 0x9cc, BIT(16) }, 1100 [RST_BUS_GPADC] = { 0x9ec, BIT(16) }, 1101 [RST_BUS_THS] = { 0x9fc, BIT(16) }, 1102 [RST_BUS_I2S0] = { 0xa20, BIT(16) }, 1103 [RST_BUS_I2S1] = { 0xa20, BIT(17) }, 1104 [RST_BUS_I2S2] = { 0xa20, BIT(18) }, 1105 [RST_BUS_I2S3] = { 0xa20, BIT(19) }, 1106 [RST_BUS_SPDIF] = { 0xa2c, BIT(16) }, 1107 [RST_BUS_DMIC] = { 0xa4c, BIT(16) }, 1108 [RST_BUS_AUDIO_CODEC] = { 0xa5c, BIT(16) }, 1109 1110 [RST_USB_PHY0] = { 0xa70, BIT(30) }, 1111 [RST_USB_PHY1] = { 0xa74, BIT(30) }, 1112 1113 [RST_BUS_OHCI0] = { 0xa8c, BIT(16) }, 1114 [RST_BUS_OHCI1] = { 0xa8c, BIT(17) }, 1115 [RST_BUS_EHCI0] = { 0xa8c, BIT(20) }, 1116 [RST_BUS_EHCI1] = { 0xa8c, BIT(21) }, 1117 [RST_BUS_OTG] = { 0xa8c, BIT(24) }, 1118 1119 [RST_BUS_LRADC] = { 0xa9c, BIT(16) }, 1120 [RST_BUS_DPSS_TOP0] = { 0xabc, BIT(16) }, 1121 [RST_BUS_DPSS_TOP1] = { 0xacc, BIT(16) }, 1122 [RST_BUS_MIPI_DSI] = { 0xb4c, BIT(16) }, 1123 [RST_BUS_TCON_LCD] = { 0xb7c, BIT(16) }, 1124 [RST_BUS_LVDS] = { 0xbac, BIT(16) }, 1125 [RST_BUS_LEDC] = { 0xbfc, BIT(16) }, 1126 [RST_BUS_CSI] = { 0xc1c, BIT(16) }, 1127 [RST_BUS_CSI_ISP] = { 0xc2c, BIT(16) }, 1128 }; 1129 1130 static const struct sunxi_ccu_desc sun50i_a100_ccu_desc = { 1131 .ccu_clks = sun50i_a100_ccu_clks, 1132 .num_ccu_clks = ARRAY_SIZE(sun50i_a100_ccu_clks), 1133 1134 .hw_clks = &sun50i_a100_hw_clks, 1135 1136 .resets = sun50i_a100_ccu_resets, 1137 .num_resets = ARRAY_SIZE(sun50i_a100_ccu_resets), 1138 }; 1139 1140 static const u32 sun50i_a100_pll_regs[] = { 1141 SUN50I_A100_PLL_CPUX_REG, 1142 SUN50I_A100_PLL_DDR0_REG, 1143 SUN50I_A100_PLL_PERIPH0_REG, 1144 SUN50I_A100_PLL_PERIPH1_REG, 1145 SUN50I_A100_PLL_GPU_REG, 1146 SUN50I_A100_PLL_VIDEO0_REG, 1147 SUN50I_A100_PLL_VIDEO1_REG, 1148 SUN50I_A100_PLL_VIDEO2_REG, 1149 SUN50I_A100_PLL_VIDEO3_REG, 1150 SUN50I_A100_PLL_VE_REG, 1151 SUN50I_A100_PLL_COM_REG, 1152 SUN50I_A100_PLL_AUDIO_REG, 1153 }; 1154 1155 static const u32 sun50i_a100_pll_video_regs[] = { 1156 SUN50I_A100_PLL_VIDEO0_REG, 1157 SUN50I_A100_PLL_VIDEO1_REG, 1158 SUN50I_A100_PLL_VIDEO2_REG, 1159 SUN50I_A100_PLL_VIDEO3_REG, 1160 }; 1161 1162 static const u32 sun50i_a100_usb2_clk_regs[] = { 1163 SUN50I_A100_USB0_CLK_REG, 1164 SUN50I_A100_USB1_CLK_REG, 1165 }; 1166 1167 static struct ccu_pll_nb sun50i_a100_pll_cpu_nb = { 1168 .common = &pll_cpux_clk.common, 1169 /* copy from pll_cpux_clk */ 1170 .enable = BIT(27), 1171 .lock = BIT(28), 1172 }; 1173 1174 static struct ccu_mux_nb sun50i_a100_cpu_nb = { 1175 .common = &cpux_clk.common, 1176 .cm = &cpux_clk.mux, 1177 .delay_us = 1, 1178 .bypass_index = 4, /* index of pll periph0 */ 1179 }; 1180 1181 static int sun50i_a100_ccu_probe(struct platform_device *pdev) 1182 { 1183 void __iomem *reg; 1184 u32 val; 1185 int i, ret; 1186 1187 reg = devm_platform_ioremap_resource(pdev, 0); 1188 if (IS_ERR(reg)) 1189 return PTR_ERR(reg); 1190 1191 /* 1192 * Enable lock and enable bits on all PLLs. 1193 * 1194 * Due to the current design, multiple PLLs share one power switch, 1195 * so switching PLL is easy to cause stability problems. 1196 * When initializing, we enable them by default. When disable, 1197 * we only turn off the output of PLL. 1198 */ 1199 for (i = 0; i < ARRAY_SIZE(sun50i_a100_pll_regs); i++) { 1200 val = readl(reg + sun50i_a100_pll_regs[i]); 1201 val |= SUN50I_A100_PLL_LOCK_ENABLE | SUN50I_A100_PLL_ENABLE; 1202 writel(val, reg + sun50i_a100_pll_regs[i]); 1203 } 1204 1205 /* 1206 * In order to pass the EMI certification, the SDM function of 1207 * the peripheral 1 bus is enabled, and the frequency is still 1208 * calculated using the previous division factor. 1209 */ 1210 writel(SUN50I_A100_PLL_PERIPH1_PATTERN0, 1211 reg + SUN50I_A100_PLL_PERIPH1_PATTERN0_REG); 1212 1213 val = readl(reg + SUN50I_A100_PLL_PERIPH1_REG); 1214 val |= SUN50I_A100_PLL_SDM_ENABLE; 1215 writel(val, reg + SUN50I_A100_PLL_PERIPH1_REG); 1216 1217 /* 1218 * Force the output divider of video PLLs to 0. 1219 * 1220 * See the comment before pll-video0 definition for the reason. 1221 */ 1222 for (i = 0; i < ARRAY_SIZE(sun50i_a100_pll_video_regs); i++) { 1223 val = readl(reg + sun50i_a100_pll_video_regs[i]); 1224 val &= ~BIT(0); 1225 writel(val, reg + sun50i_a100_pll_video_regs[i]); 1226 } 1227 1228 /* 1229 * Enforce m1 = 0, m0 = 1 for Audio PLL 1230 * 1231 * See the comment before pll-audio definition for the reason. 1232 */ 1233 val = readl(reg + SUN50I_A100_PLL_AUDIO_REG); 1234 val &= ~BIT(1); 1235 val |= BIT(0); 1236 writel(val, reg + SUN50I_A100_PLL_AUDIO_REG); 1237 1238 /* 1239 * Force OHCI 12M clock sources to 00 (12MHz divided from 48MHz) 1240 * 1241 * This clock mux is still mysterious, and the code just enforces 1242 * it to have a valid clock parent. 1243 */ 1244 for (i = 0; i < ARRAY_SIZE(sun50i_a100_usb2_clk_regs); i++) { 1245 val = readl(reg + sun50i_a100_usb2_clk_regs[i]); 1246 val &= ~GENMASK(25, 24); 1247 writel(val, reg + sun50i_a100_usb2_clk_regs[i]); 1248 } 1249 1250 ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_ccu_desc); 1251 if (ret) 1252 return ret; 1253 1254 /* Gate then ungate PLL CPU after any rate changes */ 1255 ccu_pll_notifier_register(&sun50i_a100_pll_cpu_nb); 1256 1257 /* Reparent CPU during PLL CPU rate changes */ 1258 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, 1259 &sun50i_a100_cpu_nb); 1260 1261 return 0; 1262 } 1263 1264 static const struct of_device_id sun50i_a100_ccu_ids[] = { 1265 { .compatible = "allwinner,sun50i-a100-ccu" }, 1266 { } 1267 }; 1268 1269 static struct platform_driver sun50i_a100_ccu_driver = { 1270 .probe = sun50i_a100_ccu_probe, 1271 .driver = { 1272 .name = "sun50i-a100-ccu", 1273 .suppress_bind_attrs = true, 1274 .of_match_table = sun50i_a100_ccu_ids, 1275 }, 1276 }; 1277 module_platform_driver(sun50i_a100_ccu_driver); 1278