linux/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2020 huangzhenwei@allwinnertech.com
   4 * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
   5 */
   6
   7#include <linux/clk-provider.h>
   8#include <linux/io.h>
   9#include <linux/module.h>
  10#include <linux/platform_device.h>
  11
  12#include "../clk.h"
  13
  14#include "ccu_common.h"
  15#include "ccu_reset.h"
  16
  17#include "ccu_div.h"
  18#include "ccu_gate.h"
  19#include "ccu_mp.h"
  20#include "ccu_mult.h"
  21#include "ccu_nk.h"
  22#include "ccu_nkm.h"
  23#include "ccu_nkmp.h"
  24#include "ccu_nm.h"
  25
  26#include "ccu-sun20i-d1.h"
  27
  28static const struct clk_parent_data osc24M[] = {
  29        { .fw_name = "hosc" }
  30};
  31
  32/*
  33 * For the CPU PLL, the output divider is described as "only for testing"
  34 * in the user manual. So it's not modelled and forced to 0.
  35 */
  36#define SUN20I_D1_PLL_CPUX_REG          0x000
  37static struct ccu_mult pll_cpux_clk = {
  38        .enable         = BIT(27),
  39        .lock           = BIT(28),
  40        .mult           = _SUNXI_CCU_MULT_MIN(8, 8, 12),
  41        .common         = {
  42                .reg            = 0x000,
  43                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-cpux", osc24M,
  44                                                           &ccu_mult_ops,
  45                                                           CLK_SET_RATE_UNGATE),
  46        },
  47};
  48
  49/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
  50#define SUN20I_D1_PLL_DDR0_REG          0x010
  51static struct ccu_nkmp pll_ddr0_clk = {
  52        .enable         = BIT(27),
  53        .lock           = BIT(28),
  54        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
  55        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
  56        .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
  57        .common         = {
  58                .reg            = 0x010,
  59                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-ddr0", osc24M,
  60                                                           &ccu_nkmp_ops,
  61                                                           CLK_SET_RATE_UNGATE),
  62        },
  63};
  64
  65#define SUN20I_D1_PLL_PERIPH0_REG       0x020
  66static struct ccu_nm pll_periph0_4x_clk = {
  67        .enable         = BIT(27),
  68        .lock           = BIT(28),
  69        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
  70        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
  71        .common         = {
  72                .reg            = 0x020,
  73                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-periph0-4x", osc24M,
  74                                                           &ccu_nm_ops,
  75                                                           CLK_SET_RATE_UNGATE),
  76        },
  77};
  78
  79static const struct clk_hw *pll_periph0_4x_hws[] = {
  80        &pll_periph0_4x_clk.common.hw
  81};
  82static SUNXI_CCU_M_HWS(pll_periph0_2x_clk, "pll-periph0-2x",
  83                       pll_periph0_4x_hws, 0x020, 16, 3, 0);
  84static SUNXI_CCU_M_HWS(pll_periph0_800M_clk, "pll-periph0-800M",
  85                       pll_periph0_4x_hws, 0x020, 20, 3, 0);
  86
  87static const struct clk_hw *pll_periph0_2x_hws[] = {
  88        &pll_periph0_2x_clk.common.hw
  89};
  90static CLK_FIXED_FACTOR_HWS(pll_periph0_clk, "pll-periph0",
  91                            pll_periph0_2x_hws, 2, 1, 0);
  92
  93static const struct clk_hw *pll_periph0_hws[] = { &pll_periph0_clk.hw };
  94static CLK_FIXED_FACTOR_HWS(pll_periph0_div3_clk, "pll-periph0-div3",
  95                            pll_periph0_2x_hws, 6, 1, 0);
  96
  97/*
  98 * For Video PLLs, the output divider is described as "only for testing"
  99 * in the user manual. So it's not modelled and forced to 0.
 100 */
 101#define SUN20I_D1_PLL_VIDEO0_REG        0x040
 102static struct ccu_nm pll_video0_4x_clk = {
 103        .enable         = BIT(27),
 104        .lock           = BIT(28),
 105        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
 106        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
 107        .common         = {
 108                .reg            = 0x040,
 109                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-video0-4x", osc24M,
 110                                                           &ccu_nm_ops,
 111                                                           CLK_SET_RATE_UNGATE),
 112        },
 113};
 114
 115static const struct clk_hw *pll_video0_4x_hws[] = {
 116        &pll_video0_4x_clk.common.hw
 117};
 118static CLK_FIXED_FACTOR_HWS(pll_video0_2x_clk, "pll-video0-2x",
 119                            pll_video0_4x_hws, 2, 1, CLK_SET_RATE_PARENT);
 120static CLK_FIXED_FACTOR_HWS(pll_video0_clk, "pll-video0",
 121                            pll_video0_4x_hws, 4, 1, CLK_SET_RATE_PARENT);
 122
 123#define SUN20I_D1_PLL_VIDEO1_REG        0x048
 124static struct ccu_nm pll_video1_4x_clk = {
 125        .enable         = BIT(27),
 126        .lock           = BIT(28),
 127        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
 128        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
 129        .common         = {
 130                .reg            = 0x048,
 131                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-video1-4x", osc24M,
 132                                                           &ccu_nm_ops,
 133                                                           CLK_SET_RATE_UNGATE),
 134        },
 135};
 136
 137static const struct clk_hw *pll_video1_4x_hws[] = {
 138        &pll_video1_4x_clk.common.hw
 139};
 140static CLK_FIXED_FACTOR_HWS(pll_video1_2x_clk, "pll-video1-2x",
 141                            pll_video1_4x_hws, 2, 1, CLK_SET_RATE_PARENT);
 142static CLK_FIXED_FACTOR_HWS(pll_video1_clk, "pll-video1",
 143                            pll_video1_4x_hws, 4, 1, CLK_SET_RATE_PARENT);
 144
 145#define SUN20I_D1_PLL_VE_REG            0x058
 146static struct ccu_nkmp pll_ve_clk = {
 147        .enable         = BIT(27),
 148        .lock           = BIT(28),
 149        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
 150        .m              = _SUNXI_CCU_DIV(1, 1), /* input divider */
 151        .p              = _SUNXI_CCU_DIV(0, 1), /* output divider */
 152        .common         = {
 153                .reg            = 0x058,
 154                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-ve", osc24M,
 155                                                           &ccu_nkmp_ops,
 156                                                           CLK_SET_RATE_UNGATE),
 157        },
 158};
 159
 160/*
 161 * PLL_AUDIO0 has m0, m1 dividers in addition to the usual N, M factors.
 162 * Since we only need one frequency from this PLL (22.5792 x 4 == 90.3168 MHz),
 163 * ignore them for now. Enforce the default for them, which is m1 = 0, m0 = 0.
 164 * The M factor must be an even number to produce a 50% duty cycle output.
 165 */
 166#define SUN20I_D1_PLL_AUDIO0_REG                0x078
 167static struct ccu_sdm_setting pll_audio0_sdm_table[] = {
 168        { .rate = 90316800, .pattern = 0xc001288d, .m = 6, .n = 22 },
 169};
 170
 171static struct ccu_nm pll_audio0_4x_clk = {
 172        .enable         = BIT(27),
 173        .lock           = BIT(28),
 174        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
 175        .m              = _SUNXI_CCU_DIV(16, 6),
 176        .sdm            = _SUNXI_CCU_SDM(pll_audio0_sdm_table, BIT(24),
 177                                         0x178, BIT(31)),
 178        .common         = {
 179                .reg            = 0x078,
 180                .features       = CCU_FEATURE_SIGMA_DELTA_MOD,
 181                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-audio0-4x", osc24M,
 182                                                           &ccu_nm_ops,
 183                                                           CLK_SET_RATE_UNGATE),
 184        },
 185};
 186
 187static const struct clk_hw *pll_audio0_4x_hws[] = {
 188        &pll_audio0_4x_clk.common.hw
 189};
 190static CLK_FIXED_FACTOR_HWS(pll_audio0_2x_clk, "pll-audio0-2x",
 191                            pll_audio0_4x_hws, 2, 1, 0);
 192static CLK_FIXED_FACTOR_HWS(pll_audio0_clk, "pll-audio0",
 193                            pll_audio0_4x_hws, 4, 1, 0);
 194
 195/*
 196 * PLL_AUDIO1 doesn't need Fractional-N. The output is usually 614.4 MHz for
 197 * audio. The ADC or DAC should divide the PLL output further to 24.576 MHz.
 198 */
 199#define SUN20I_D1_PLL_AUDIO1_REG                0x080
 200static struct ccu_nm pll_audio1_clk = {
 201        .enable         = BIT(27),
 202        .lock           = BIT(28),
 203        .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
 204        .m              = _SUNXI_CCU_DIV(1, 1),
 205        .common         = {
 206                .reg            = 0x080,
 207                .hw.init        = CLK_HW_INIT_PARENTS_DATA("pll-audio1", osc24M,
 208                                                           &ccu_nm_ops,
 209                                                           CLK_SET_RATE_UNGATE),
 210        },
 211};
 212
 213static const struct clk_hw *pll_audio1_hws[] = {
 214        &pll_audio1_clk.common.hw
 215};
 216static SUNXI_CCU_M_HWS(pll_audio1_div2_clk, "pll-audio1-div2",
 217                       pll_audio1_hws, 0x080, 16, 3, 0);
 218static SUNXI_CCU_M_HWS(pll_audio1_div5_clk, "pll-audio1-div5",
 219                       pll_audio1_hws, 0x080, 20, 3, 0);
 220
 221/*
 222 * The CPUX gate is not modelled - it is in a separate register (0x504)
 223 * and has a special key field. The clock does not need to be ungated anyway.
 224 */
 225static const struct clk_parent_data cpux_parents[] = {
 226        { .fw_name = "hosc" },
 227        { .fw_name = "losc" },
 228        { .fw_name = "iosc" },
 229        { .hw = &pll_cpux_clk.common.hw },
 230        { .hw = &pll_periph0_clk.hw },
 231        { .hw = &pll_periph0_2x_clk.common.hw },
 232        { .hw = &pll_periph0_800M_clk.common.hw },
 233};
 234static SUNXI_CCU_MUX_DATA(cpux_clk, "cpux", cpux_parents,
 235                          0x500, 24, 3, CLK_SET_RATE_PARENT);
 236
 237static const struct clk_hw *cpux_hws[] = { &cpux_clk.common.hw };
 238static SUNXI_CCU_M_HWS(cpux_axi_clk, "cpux-axi",
 239                       cpux_hws, 0x500, 0, 2, 0);
 240static SUNXI_CCU_M_HWS(cpux_apb_clk, "cpux-apb",
 241                       cpux_hws, 0x500, 8, 2, 0);
 242
 243static const struct clk_parent_data psi_ahb_parents[] = {
 244        { .fw_name = "hosc" },
 245        { .fw_name = "losc" },
 246        { .fw_name = "iosc" },
 247        { .hw = &pll_periph0_clk.hw },
 248};
 249static SUNXI_CCU_MP_DATA_WITH_MUX(psi_ahb_clk, "psi-ahb", psi_ahb_parents, 0x510,
 250                                  0, 2,         /* M */
 251                                  8, 2,         /* P */
 252                                  24, 2,        /* mux */
 253                                  0);
 254
 255static const struct clk_parent_data apb0_apb1_parents[] = {
 256        { .fw_name = "hosc" },
 257        { .fw_name = "losc" },
 258        { .hw = &psi_ahb_clk.common.hw },
 259        { .hw = &pll_periph0_clk.hw },
 260};
 261static SUNXI_CCU_MP_DATA_WITH_MUX(apb0_clk, "apb0", apb0_apb1_parents, 0x520,
 262                                  0, 5,         /* M */
 263                                  8, 2,         /* P */
 264                                  24, 2,        /* mux */
 265                                  0);
 266
 267static SUNXI_CCU_MP_DATA_WITH_MUX(apb1_clk, "apb1", apb0_apb1_parents, 0x524,
 268                                  0, 5,         /* M */
 269                                  8, 2,         /* P */
 270                                  24, 2,        /* mux */
 271                                  0);
 272
 273static const struct clk_hw *psi_ahb_hws[] = { &psi_ahb_clk.common.hw };
 274static const struct clk_hw *apb0_hws[] = { &apb0_clk.common.hw };
 275static const struct clk_hw *apb1_hws[] = { &apb1_clk.common.hw };
 276
 277static const struct clk_hw *de_di_g2d_parents[] = {
 278        &pll_periph0_2x_clk.common.hw,
 279        &pll_video0_4x_clk.common.hw,
 280        &pll_video1_4x_clk.common.hw,
 281        &pll_audio1_div2_clk.common.hw,
 282};
 283static SUNXI_CCU_M_HW_WITH_MUX_GATE(de_clk, "de", de_di_g2d_parents, 0x600,
 284                                    0, 5,       /* M */
 285                                    24, 3,      /* mux */
 286                                    BIT(31),    /* gate */
 287                                    CLK_SET_RATE_PARENT);
 288
 289static SUNXI_CCU_GATE_HWS(bus_de_clk, "bus-de", psi_ahb_hws,
 290                          0x60c, BIT(0), 0);
 291
 292static SUNXI_CCU_M_HW_WITH_MUX_GATE(di_clk, "di", de_di_g2d_parents, 0x620,
 293                                    0, 5,       /* M */
 294                                    24, 3,      /* mux */
 295                                    BIT(31),    /* gate */
 296                                    CLK_SET_RATE_PARENT);
 297
 298static SUNXI_CCU_GATE_HWS(bus_di_clk, "bus-di", psi_ahb_hws,
 299                          0x62c, BIT(0), 0);
 300
 301static SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", de_di_g2d_parents, 0x630,
 302                                    0, 5,       /* M */
 303                                    24, 3,      /* mux */
 304                                    BIT(31),    /* gate */
 305                                    0);
 306
 307static SUNXI_CCU_GATE_HWS(bus_g2d_clk, "bus-g2d", psi_ahb_hws,
 308                          0x63c, BIT(0), 0);
 309
 310static const struct clk_parent_data ce_parents[] = {
 311        { .fw_name = "hosc" },
 312        { .hw = &pll_periph0_2x_clk.common.hw },
 313        { .hw = &pll_periph0_clk.hw },
 314};
 315static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x680,
 316                                       0, 4,    /* M */
 317                                       8, 2,    /* P */
 318                                       24, 3,   /* mux */
 319                                       BIT(31), /* gate */
 320                                       0);
 321
 322static SUNXI_CCU_GATE_HWS(bus_ce_clk, "bus-ce", psi_ahb_hws,
 323                          0x68c, BIT(0), 0);
 324
 325static const struct clk_hw *ve_parents[] = {
 326        &pll_ve_clk.common.hw,
 327        &pll_periph0_2x_clk.common.hw,
 328};
 329static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_clk, "ve", ve_parents, 0x690,
 330                                    0, 5,       /* M */
 331                                    24, 1,      /* mux */
 332                                    BIT(31),    /* gate */
 333                                    CLK_SET_RATE_PARENT);
 334
 335static SUNXI_CCU_GATE_HWS(bus_ve_clk, "bus-ve", psi_ahb_hws,
 336                          0x69c, BIT(0), 0);
 337
 338static SUNXI_CCU_GATE_HWS(bus_dma_clk, "bus-dma", psi_ahb_hws,
 339                          0x70c, BIT(0), 0);
 340
 341static SUNXI_CCU_GATE_HWS(bus_msgbox0_clk, "bus-msgbox0", psi_ahb_hws,
 342                          0x71c, BIT(0), 0);
 343static SUNXI_CCU_GATE_HWS(bus_msgbox1_clk, "bus-msgbox1", psi_ahb_hws,
 344                          0x71c, BIT(1), 0);
 345static SUNXI_CCU_GATE_HWS(bus_msgbox2_clk, "bus-msgbox2", psi_ahb_hws,
 346                          0x71c, BIT(2), 0);
 347
 348static SUNXI_CCU_GATE_HWS(bus_spinlock_clk, "bus-spinlock", psi_ahb_hws,
 349                          0x72c, BIT(0), 0);
 350
 351static SUNXI_CCU_GATE_HWS(bus_hstimer_clk, "bus-hstimer", psi_ahb_hws,
 352                          0x73c, BIT(0), 0);
 353
 354static SUNXI_CCU_GATE_DATA(avs_clk, "avs", osc24M,
 355                           0x740, BIT(31), 0);
 356
 357static SUNXI_CCU_GATE_HWS(bus_dbg_clk, "bus-dbg", psi_ahb_hws,
 358                          0x78c, BIT(0), 0);
 359
 360static SUNXI_CCU_GATE_HWS(bus_pwm_clk, "bus-pwm", apb0_hws,
 361                          0x7ac, BIT(0), 0);
 362
 363static SUNXI_CCU_GATE_HWS(bus_iommu_clk, "bus-iommu", apb0_hws,
 364                          0x7bc, BIT(0), 0);
 365
 366static const struct clk_hw *dram_parents[] = {
 367        &pll_ddr0_clk.common.hw,
 368        &pll_audio1_div2_clk.common.hw,
 369        &pll_periph0_2x_clk.common.hw,
 370        &pll_periph0_800M_clk.common.hw,
 371};
 372static SUNXI_CCU_MP_HW_WITH_MUX_GATE(dram_clk, "dram", dram_parents, 0x800,
 373                                     0, 2,      /* M */
 374                                     8, 2,      /* P */
 375                                     24, 2,     /* mux */
 376                                     BIT(31), CLK_IS_CRITICAL);
 377
 378static CLK_FIXED_FACTOR_HW(mbus_clk, "mbus",
 379                           &dram_clk.common.hw, 4, 1, 0);
 380
 381static const struct clk_hw *mbus_hws[] = { &mbus_clk.hw };
 382
 383static SUNXI_CCU_GATE_HWS(mbus_dma_clk, "mbus-dma", mbus_hws,
 384                          0x804, BIT(0), 0);
 385static SUNXI_CCU_GATE_HWS(mbus_ve_clk, "mbus-ve", mbus_hws,
 386                          0x804, BIT(1), 0);
 387static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
 388                          0x804, BIT(2), 0);
 389static SUNXI_CCU_GATE_HWS(mbus_tvin_clk, "mbus-tvin", mbus_hws,
 390                          0x804, BIT(7), 0);
 391static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
 392                          0x804, BIT(8), 0);
 393static SUNXI_CCU_GATE_HWS(mbus_g2d_clk, "mbus-g2d", mbus_hws,
 394                          0x804, BIT(10), 0);
 395static SUNXI_CCU_GATE_HWS(mbus_riscv_clk, "mbus-riscv", mbus_hws,
 396                          0x804, BIT(11), 0);
 397
 398static SUNXI_CCU_GATE_HWS(bus_dram_clk, "bus-dram", psi_ahb_hws,
 399                          0x80c, BIT(0), CLK_IS_CRITICAL);
 400
 401static const struct clk_parent_data mmc0_mmc1_parents[] = {
 402        { .fw_name = "hosc" },
 403        { .hw = &pll_periph0_clk.hw },
 404        { .hw = &pll_periph0_2x_clk.common.hw },
 405        { .hw = &pll_audio1_div2_clk.common.hw },
 406};
 407static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc0_mmc1_parents, 0x830,
 408                                       0, 4,    /* M */
 409                                       8, 2,    /* P */
 410                                       24, 3,   /* mux */
 411                                       BIT(31), /* gate */
 412                                       0);
 413
 414static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc0_mmc1_parents, 0x834,
 415                                       0, 4,    /* M */
 416                                       8, 2,    /* P */
 417                                       24, 3,   /* mux */
 418                                       BIT(31), /* gate */
 419                                       0);
 420
 421static const struct clk_parent_data mmc2_parents[] = {
 422        { .fw_name = "hosc" },
 423        { .hw = &pll_periph0_clk.hw },
 424        { .hw = &pll_periph0_2x_clk.common.hw },
 425        { .hw = &pll_periph0_800M_clk.common.hw },
 426        { .hw = &pll_audio1_div2_clk.common.hw },
 427};
 428static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc2_parents, 0x838,
 429                                       0, 4,    /* M */
 430                                       8, 2,    /* P */
 431                                       24, 3,   /* mux */
 432                                       BIT(31), /* gate */
 433                                       0);
 434
 435static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", psi_ahb_hws,
 436                          0x84c, BIT(0), 0);
 437static SUNXI_CCU_GATE_HWS(bus_mmc1_clk, "bus-mmc1", psi_ahb_hws,
 438                          0x84c, BIT(1), 0);
 439static SUNXI_CCU_GATE_HWS(bus_mmc2_clk, "bus-mmc2", psi_ahb_hws,
 440                          0x84c, BIT(2), 0);
 441
 442static SUNXI_CCU_GATE_HWS(bus_uart0_clk, "bus-uart0", apb1_hws,
 443                          0x90c, BIT(0), 0);
 444static SUNXI_CCU_GATE_HWS(bus_uart1_clk, "bus-uart1", apb1_hws,
 445                          0x90c, BIT(1), 0);
 446static SUNXI_CCU_GATE_HWS(bus_uart2_clk, "bus-uart2", apb1_hws,
 447                          0x90c, BIT(2), 0);
 448static SUNXI_CCU_GATE_HWS(bus_uart3_clk, "bus-uart3", apb1_hws,
 449                          0x90c, BIT(3), 0);
 450static SUNXI_CCU_GATE_HWS(bus_uart4_clk, "bus-uart4", apb1_hws,
 451                          0x90c, BIT(4), 0);
 452static SUNXI_CCU_GATE_HWS(bus_uart5_clk, "bus-uart5", apb1_hws,
 453                          0x90c, BIT(5), 0);
 454
 455static SUNXI_CCU_GATE_HWS(bus_i2c0_clk, "bus-i2c0", apb1_hws,
 456                          0x91c, BIT(0), 0);
 457static SUNXI_CCU_GATE_HWS(bus_i2c1_clk, "bus-i2c1", apb1_hws,
 458                          0x91c, BIT(1), 0);
 459static SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws,
 460                          0x91c, BIT(2), 0);
 461static SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws,
 462                          0x91c, BIT(3), 0);
 463
 464static const struct clk_parent_data spi_parents[] = {
 465        { .fw_name = "hosc" },
 466        { .hw = &pll_periph0_clk.hw },
 467        { .hw = &pll_periph0_2x_clk.common.hw },
 468        { .hw = &pll_audio1_div2_clk.common.hw },
 469        { .hw = &pll_audio1_div5_clk.common.hw },
 470};
 471static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi0_clk, "spi0", spi_parents, 0x940,
 472                                       0, 4,    /* M */
 473                                       8, 2,    /* P */
 474                                       24, 3,   /* mux */
 475                                       BIT(31), /* gate */
 476                                       0);
 477
 478static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(spi1_clk, "spi1", spi_parents, 0x944,
 479                                       0, 4,    /* M */
 480                                       8, 2,    /* P */
 481                                       24, 3,   /* mux */
 482                                       BIT(31), /* gate */
 483                                       0);
 484
 485static SUNXI_CCU_GATE_HWS(bus_spi0_clk, "bus-spi0", psi_ahb_hws,
 486                          0x96c, BIT(0), 0);
 487static SUNXI_CCU_GATE_HWS(bus_spi1_clk, "bus-spi1", psi_ahb_hws,
 488                          0x96c, BIT(1), 0);
 489
 490static SUNXI_CCU_GATE_HWS_WITH_PREDIV(emac_25M_clk, "emac-25M", pll_periph0_hws,
 491                                      0x970, BIT(31) | BIT(30), 24, 0);
 492
 493static SUNXI_CCU_GATE_HWS(bus_emac_clk, "bus-emac", psi_ahb_hws,
 494                          0x97c, BIT(0), 0);
 495
 496static const struct clk_parent_data ir_tx_ledc_parents[] = {
 497        { .fw_name = "hosc" },
 498        { .hw = &pll_periph0_clk.hw },
 499};
 500static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ir_tx_clk, "ir-tx", ir_tx_ledc_parents, 0x9c0,
 501                                       0, 4,    /* M */
 502                                       8, 2,    /* P */
 503                                       24, 3,   /* mux */
 504                                       BIT(31), /* gate */
 505                                       0);
 506
 507static SUNXI_CCU_GATE_HWS(bus_ir_tx_clk, "bus-ir-tx", apb0_hws,
 508                          0x9cc, BIT(0), 0);
 509
 510static SUNXI_CCU_GATE_HWS(bus_gpadc_clk, "bus-gpadc", apb0_hws,
 511                          0x9ec, BIT(0), 0);
 512
 513static SUNXI_CCU_GATE_HWS(bus_ths_clk, "bus-ths", apb0_hws,
 514                          0x9fc, BIT(0), 0);
 515
 516static const struct clk_hw *i2s_spdif_tx_parents[] = {
 517        &pll_audio0_clk.hw,
 518        &pll_audio0_4x_clk.common.hw,
 519        &pll_audio1_div2_clk.common.hw,
 520        &pll_audio1_div5_clk.common.hw,
 521};
 522static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s0_clk, "i2s0", i2s_spdif_tx_parents, 0xa10,
 523                                     0, 5,      /* M */
 524                                     8, 2,      /* P */
 525                                     24, 3,     /* mux */
 526                                     BIT(31),   /* gate */
 527                                     0);
 528
 529static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s1_clk, "i2s1", i2s_spdif_tx_parents, 0xa14,
 530                                     0, 5,      /* M */
 531                                     8, 2,      /* P */
 532                                     24, 3,     /* mux */
 533                                     BIT(31),   /* gate */
 534                                     0);
 535
 536static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s2_clk, "i2s2", i2s_spdif_tx_parents, 0xa18,
 537                                     0, 5,      /* M */
 538                                     8, 2,      /* P */
 539                                     24, 3,     /* mux */
 540                                     BIT(31),   /* gate */
 541                                     0);
 542
 543static const struct clk_hw *i2s2_asrc_parents[] = {
 544        &pll_audio0_4x_clk.common.hw,
 545        &pll_periph0_clk.hw,
 546        &pll_audio1_div2_clk.common.hw,
 547        &pll_audio1_div5_clk.common.hw,
 548};
 549static SUNXI_CCU_MP_HW_WITH_MUX_GATE(i2s2_asrc_clk, "i2s2-asrc", i2s2_asrc_parents, 0xa1c,
 550                                     0, 5,      /* M */
 551                                     8, 2,      /* P */
 552                                     24, 3,     /* mux */
 553                                     BIT(31),   /* gate */
 554                                     0);
 555
 556static SUNXI_CCU_GATE_HWS(bus_i2s0_clk, "bus-i2s0", apb0_hws,
 557                          0xa20, BIT(0), 0);
 558static SUNXI_CCU_GATE_HWS(bus_i2s1_clk, "bus-i2s1", apb0_hws,
 559                          0xa20, BIT(1), 0);
 560static SUNXI_CCU_GATE_HWS(bus_i2s2_clk, "bus-i2s2", apb0_hws,
 561                          0xa20, BIT(2), 0);
 562
 563static SUNXI_CCU_MP_HW_WITH_MUX_GATE(spdif_tx_clk, "spdif-tx", i2s_spdif_tx_parents, 0xa24,
 564                                     0, 5,      /* M */
 565                                     8, 2,      /* P */
 566                                     24, 3,     /* mux */
 567                                     BIT(31),   /* gate */
 568                                     0);
 569
 570static const struct clk_hw *spdif_rx_parents[] = {
 571        &pll_periph0_clk.hw,
 572        &pll_audio1_div2_clk.common.hw,
 573        &pll_audio1_div5_clk.common.hw,
 574};
 575static SUNXI_CCU_MP_HW_WITH_MUX_GATE(spdif_rx_clk, "spdif-rx", spdif_rx_parents, 0xa28,
 576                                     0, 5,      /* M */
 577                                     8, 2,      /* P */
 578                                     24, 3,     /* mux */
 579                                     BIT(31),   /* gate */
 580                                     0);
 581
 582static SUNXI_CCU_GATE_HWS(bus_spdif_clk, "bus-spdif", apb0_hws,
 583                          0xa2c, BIT(0), 0);
 584
 585static const struct clk_hw *dmic_codec_parents[] = {
 586        &pll_audio0_clk.hw,
 587        &pll_audio1_div2_clk.common.hw,
 588        &pll_audio1_div5_clk.common.hw,
 589};
 590static SUNXI_CCU_MP_HW_WITH_MUX_GATE(dmic_clk, "dmic", dmic_codec_parents, 0xa40,
 591                                     0, 5,      /* M */
 592                                     8, 2,      /* P */
 593                                     24, 3,     /* mux */
 594                                     BIT(31),   /* gate */
 595                                     0);
 596
 597static SUNXI_CCU_GATE_HWS(bus_dmic_clk, "bus-dmic", apb0_hws,
 598                          0xa4c, BIT(0), 0);
 599
 600static SUNXI_CCU_MP_HW_WITH_MUX_GATE(audio_dac_clk, "audio-dac", dmic_codec_parents, 0xa50,
 601                                     0, 5,      /* M */
 602                                     8, 2,      /* P */
 603                                     24, 3,     /* mux */
 604                                     BIT(31),   /* gate */
 605                                     0);
 606
 607static SUNXI_CCU_MP_HW_WITH_MUX_GATE(audio_adc_clk, "audio-adc", dmic_codec_parents, 0xa54,
 608                                     0, 5,      /* M */
 609                                     8, 2,      /* P */
 610                                     24, 3,     /* mux */
 611                                     BIT(31),   /* gate */
 612                                     0);
 613
 614static SUNXI_CCU_GATE_HWS(bus_audio_clk, "bus-audio", apb0_hws,
 615                          0xa5c, BIT(0), 0);
 616
 617
 618/*
 619 * The first parent is a 48 MHz input clock divided by 4. That 48 MHz clock is
 620 * a 2x multiplier from osc24M synchronized by pll-periph0, and is also used by
 621 * the OHCI module.
 622 */
 623static const struct clk_parent_data usb_ohci_parents[] = {
 624        { .hw = &pll_periph0_clk.hw },
 625        { .fw_name = "hosc" },
 626        { .fw_name = "losc" },
 627};
 628static const struct ccu_mux_fixed_prediv usb_ohci_predivs[] = {
 629        { .index = 0, .div = 50 },
 630        { .index = 1, .div = 2 },
 631};
 632
 633static struct ccu_mux usb_ohci0_clk = {
 634        .enable         = BIT(31),
 635        .mux            = {
 636                .shift          = 24,
 637                .width          = 2,
 638                .fixed_predivs  = usb_ohci_predivs,
 639                .n_predivs      = ARRAY_SIZE(usb_ohci_predivs),
 640        },
 641        .common         = {
 642                .reg            = 0xa70,
 643                .features       = CCU_FEATURE_FIXED_PREDIV,
 644                .hw.init        = CLK_HW_INIT_PARENTS_DATA("usb-ohci0",
 645                                                           usb_ohci_parents,
 646                                                           &ccu_mux_ops,
 647                                                           0),
 648        },
 649};
 650
 651static struct ccu_mux usb_ohci1_clk = {
 652        .enable         = BIT(31),
 653        .mux            = {
 654                .shift          = 24,
 655                .width          = 2,
 656                .fixed_predivs  = usb_ohci_predivs,
 657                .n_predivs      = ARRAY_SIZE(usb_ohci_predivs),
 658        },
 659        .common         = {
 660                .reg            = 0xa74,
 661                .features       = CCU_FEATURE_FIXED_PREDIV,
 662                .hw.init        = CLK_HW_INIT_PARENTS_DATA("usb-ohci1",
 663                                                           usb_ohci_parents,
 664                                                           &ccu_mux_ops,
 665                                                           0),
 666        },
 667};
 668
 669static SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", psi_ahb_hws,
 670                          0xa8c, BIT(0), 0);
 671static SUNXI_CCU_GATE_HWS(bus_ohci1_clk, "bus-ohci1", psi_ahb_hws,
 672                          0xa8c, BIT(1), 0);
 673static SUNXI_CCU_GATE_HWS(bus_ehci0_clk, "bus-ehci0", psi_ahb_hws,
 674                          0xa8c, BIT(4), 0);
 675static SUNXI_CCU_GATE_HWS(bus_ehci1_clk, "bus-ehci1", psi_ahb_hws,
 676                          0xa8c, BIT(5), 0);
 677static SUNXI_CCU_GATE_HWS(bus_otg_clk, "bus-otg", psi_ahb_hws,
 678                          0xa8c, BIT(8), 0);
 679
 680static SUNXI_CCU_GATE_HWS(bus_lradc_clk, "bus-lradc", apb0_hws,
 681                          0xa9c, BIT(0), 0);
 682
 683static SUNXI_CCU_GATE_HWS(bus_dpss_top_clk, "bus-dpss-top", psi_ahb_hws,
 684                          0xabc, BIT(0), 0);
 685
 686static SUNXI_CCU_GATE_DATA(hdmi_24M_clk, "hdmi-24M", osc24M,
 687                           0xb04, BIT(31), 0);
 688
 689static SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k",
 690                                      pll_periph0_2x_hws,
 691                                      0xb10, BIT(30), 36621, 0);
 692
 693static const struct clk_parent_data hdmi_cec_parents[] = {
 694        { .fw_name = "losc" },
 695        { .hw = &hdmi_cec_32k_clk.common.hw },
 696};
 697static SUNXI_CCU_MUX_DATA_WITH_GATE(hdmi_cec_clk, "hdmi-cec", hdmi_cec_parents, 0xb10,
 698                                    24, 1,      /* mux */
 699                                    BIT(31),    /* gate */
 700                                    0);
 701
 702static SUNXI_CCU_GATE_HWS(bus_hdmi_clk, "bus-hdmi", psi_ahb_hws,
 703                          0xb1c, BIT(0), 0);
 704
 705static const struct clk_parent_data mipi_dsi_parents[] = {
 706        { .fw_name = "hosc" },
 707        { .hw = &pll_periph0_clk.hw },
 708        { .hw = &pll_video0_2x_clk.hw },
 709        { .hw = &pll_video1_2x_clk.hw },
 710        { .hw = &pll_audio1_div2_clk.common.hw },
 711};
 712static SUNXI_CCU_M_DATA_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", mipi_dsi_parents, 0xb24,
 713                                      0, 4,     /* M */
 714                                      24, 3,    /* mux */
 715                                      BIT(31),  /* gate */
 716                                      CLK_SET_RATE_PARENT);
 717
 718static SUNXI_CCU_GATE_HWS(bus_mipi_dsi_clk, "bus-mipi-dsi", psi_ahb_hws,
 719                          0xb4c, BIT(0), 0);
 720
 721static const struct clk_hw *tcon_tve_parents[] = {
 722        &pll_video0_clk.hw,
 723        &pll_video0_4x_clk.common.hw,
 724        &pll_video1_clk.hw,
 725        &pll_video1_4x_clk.common.hw,
 726        &pll_periph0_2x_clk.common.hw,
 727        &pll_audio1_div2_clk.common.hw,
 728};
 729static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_tve_parents, 0xb60,
 730                                     0, 4,      /* M */
 731                                     8, 2,      /* P */
 732                                     24, 3,     /* mux */
 733                                     BIT(31),   /* gate */
 734                                     CLK_SET_RATE_PARENT);
 735
 736static SUNXI_CCU_GATE_HWS(bus_tcon_lcd0_clk, "bus-tcon-lcd0", psi_ahb_hws,
 737                          0xb7c, BIT(0), 0);
 738
 739static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tcon_tv_clk, "tcon-tv", tcon_tve_parents, 0xb80,
 740                                     0, 4,      /* M */
 741                                     8, 2,      /* P */
 742                                     24, 3,     /* mux */
 743                                     BIT(31),   /* gate */
 744                                     CLK_SET_RATE_PARENT);
 745
 746static SUNXI_CCU_GATE_HWS(bus_tcon_tv_clk, "bus-tcon-tv", psi_ahb_hws,
 747                          0xb9c, BIT(0), 0);
 748
 749static SUNXI_CCU_MP_HW_WITH_MUX_GATE(tve_clk, "tve", tcon_tve_parents, 0xbb0,
 750                                     0, 4,      /* M */
 751                                     8, 2,      /* P */
 752                                     24, 3,     /* mux */
 753                                     BIT(31),   /* gate */
 754                                     0);
 755
 756static SUNXI_CCU_GATE_HWS(bus_tve_top_clk, "bus-tve-top", psi_ahb_hws,
 757                          0xbbc, BIT(0), 0);
 758static SUNXI_CCU_GATE_HWS(bus_tve_clk, "bus-tve", psi_ahb_hws,
 759                          0xbbc, BIT(1), 0);
 760
 761static const struct clk_parent_data tvd_parents[] = {
 762        { .fw_name = "hosc" },
 763        { .hw = &pll_video0_clk.hw },
 764        { .hw = &pll_video1_clk.hw },
 765        { .hw = &pll_periph0_clk.hw },
 766};
 767static SUNXI_CCU_M_DATA_WITH_MUX_GATE(tvd_clk, "tvd", tvd_parents, 0xbc0,
 768                                      0, 5,     /* M */
 769                                      24, 3,    /* mux */
 770                                      BIT(31),  /* gate */
 771                                      0);
 772
 773static SUNXI_CCU_GATE_HWS(bus_tvd_top_clk, "bus-tvd-top", psi_ahb_hws,
 774                          0xbdc, BIT(0), 0);
 775static SUNXI_CCU_GATE_HWS(bus_tvd_clk, "bus-tvd", psi_ahb_hws,
 776                          0xbdc, BIT(1), 0);
 777
 778static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ir_tx_ledc_parents, 0xbf0,
 779                                       0, 4,    /* M */
 780                                       8, 2,    /* P */
 781                                       24, 1,   /* mux */
 782                                       BIT(31), /* gate */
 783                                       0);
 784
 785static SUNXI_CCU_GATE_HWS(bus_ledc_clk, "bus-ledc", psi_ahb_hws,
 786                          0xbfc, BIT(0), 0);
 787
 788static const struct clk_hw *csi_top_parents[] = {
 789        &pll_periph0_2x_clk.common.hw,
 790        &pll_video0_2x_clk.hw,
 791        &pll_video1_2x_clk.hw,
 792};
 793static SUNXI_CCU_M_HW_WITH_MUX_GATE(csi_top_clk, "csi-top", csi_top_parents, 0xc04,
 794                                    0, 4,       /* M */
 795                                    24, 3,      /* mux */
 796                                    BIT(31),    /* gate */
 797                                    0);
 798
 799static const struct clk_parent_data csi_mclk_parents[] = {
 800        { .fw_name = "hosc" },
 801        { .hw = &pll_periph0_clk.hw },
 802        { .hw = &pll_video0_clk.hw },
 803        { .hw = &pll_video1_clk.hw },
 804        { .hw = &pll_audio1_div2_clk.common.hw },
 805        { .hw = &pll_audio1_div5_clk.common.hw },
 806};
 807static SUNXI_CCU_M_DATA_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", csi_mclk_parents, 0xc08,
 808                                      0, 5,     /* M */
 809                                      24, 3,    /* mux */
 810                                      BIT(31),  /* gate */
 811                                      0);
 812
 813static SUNXI_CCU_GATE_HWS(bus_csi_clk, "bus-csi", psi_ahb_hws,
 814                          0xc1c, BIT(0), 0);
 815
 816static const struct clk_parent_data tpadc_parents[] = {
 817        { .fw_name = "hosc" },
 818        { .hw = &pll_audio0_clk.hw },
 819};
 820static SUNXI_CCU_MUX_DATA_WITH_GATE(tpadc_clk, "tpadc", tpadc_parents, 0xc50,
 821                                    24, 3,      /* mux */
 822                                    BIT(31),    /* gate */
 823                                    0);
 824
 825static SUNXI_CCU_GATE_HWS(bus_tpadc_clk, "bus-tpadc", apb0_hws,
 826                          0xc5c, BIT(0), 0);
 827
 828static SUNXI_CCU_GATE_HWS(bus_tzma_clk, "bus-tzma", apb0_hws,
 829                          0xc6c, BIT(0), 0);
 830
 831static const struct clk_parent_data dsp_parents[] = {
 832        { .fw_name = "hosc" },
 833        { .fw_name = "losc" },
 834        { .fw_name = "iosc" },
 835        { .hw = &pll_periph0_2x_clk.common.hw },
 836        { .hw = &pll_audio1_div2_clk.common.hw },
 837};
 838static SUNXI_CCU_M_DATA_WITH_MUX_GATE(dsp_clk, "dsp", dsp_parents, 0xc70,
 839                                      0, 5,     /* M */
 840                                      24, 3,    /* mux */
 841                                      BIT(31),  /* gate */
 842                                      0);
 843
 844static SUNXI_CCU_GATE_HWS(bus_dsp_cfg_clk, "bus-dsp-cfg", psi_ahb_hws,
 845                          0xc7c, BIT(1), 0);
 846
 847/*
 848 * The RISC-V gate is not modelled - it is in a separate register (0xd04)
 849 * and has a special key field. The clock is critical anyway.
 850 */
 851static const struct clk_parent_data riscv_parents[] = {
 852        { .fw_name = "hosc" },
 853        { .fw_name = "losc" },
 854        { .fw_name = "iosc" },
 855        { .hw = &pll_periph0_800M_clk.common.hw },
 856        { .hw = &pll_periph0_clk.hw },
 857        { .hw = &pll_cpux_clk.common.hw },
 858        { .hw = &pll_audio1_div2_clk.common.hw },
 859};
 860static SUNXI_CCU_M_DATA_WITH_MUX(riscv_clk, "riscv", riscv_parents, 0xd00,
 861                                 0, 5,  /* M */
 862                                 24, 3, /* mux */
 863                                 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
 864
 865/* The riscv-axi clk must be divided by at least 2. */
 866static struct clk_div_table riscv_axi_table[] = {
 867        { .val = 1, .div = 2 },
 868        { .val = 2, .div = 3 },
 869        { .val = 3, .div = 4 },
 870        { /* Sentinel */ }
 871};
 872static SUNXI_CCU_DIV_TABLE_HW(riscv_axi_clk, "riscv-axi", &riscv_clk.common.hw,
 873                              0xd00, 8, 2, riscv_axi_table, 0);
 874
 875static SUNXI_CCU_GATE_HWS(bus_riscv_cfg_clk, "bus-riscv-cfg", psi_ahb_hws,
 876                          0xd0c, BIT(0), CLK_IS_CRITICAL);
 877
 878static SUNXI_CCU_GATE_DATA(fanout_24M_clk, "fanout-24M", osc24M,
 879                           0xf30, BIT(0), 0);
 880static SUNXI_CCU_GATE_DATA_WITH_PREDIV(fanout_12M_clk, "fanout-12M", osc24M,
 881                                       0xf30, BIT(1), 2, 0);
 882static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_16M_clk, "fanout-16M", pll_periph0_2x_hws,
 883                                      0xf30, BIT(2), 75, 0);
 884static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_25M_clk, "fanout-25M", pll_periph0_hws,
 885                                      0xf30, BIT(3), 24, 0);
 886static SUNXI_CCU_GATE_HWS_WITH_PREDIV(fanout_32k_clk, "fanout-32k", pll_periph0_2x_hws,
 887                                      0xf30, BIT(4), 36621, 0);
 888
 889/* This clock has a second divider that is not modelled and forced to 0. */
 890#define SUN20I_D1_FANOUT_27M_REG        0xf34
 891static const struct clk_hw *fanout_27M_parents[] = {
 892        &pll_video0_clk.hw,
 893        &pll_video1_clk.hw,
 894};
 895static SUNXI_CCU_M_HW_WITH_MUX_GATE(fanout_27M_clk, "fanout-27M", fanout_27M_parents, 0xf34,
 896                                    0, 5,       /* M */
 897                                    24, 2,      /* mux */
 898                                    BIT(31),    /* gate */
 899                                    0);
 900
 901static SUNXI_CCU_M_HWS_WITH_GATE(fanout_pclk_clk, "fanout-pclk", apb0_hws, 0xf38,
 902                                 0, 5,          /* M */
 903                                 BIT(31),       /* gate */
 904                                 0);
 905
 906static const struct clk_hw *fanout_parents[] = {
 907        &fanout_32k_clk.common.hw,
 908        &fanout_12M_clk.common.hw,
 909        &fanout_16M_clk.common.hw,
 910        &fanout_24M_clk.common.hw,
 911        &fanout_25M_clk.common.hw,
 912        &fanout_27M_clk.common.hw,
 913        &fanout_pclk_clk.common.hw,
 914};
 915static SUNXI_CCU_MUX_HW_WITH_GATE(fanout0_clk, "fanout0", fanout_parents, 0xf3c,
 916                                  0, 3,         /* mux */
 917                                  BIT(21),      /* gate */
 918                                  0);
 919static SUNXI_CCU_MUX_HW_WITH_GATE(fanout1_clk, "fanout1", fanout_parents, 0xf3c,
 920                                  3, 3,         /* mux */
 921                                  BIT(22),      /* gate */
 922                                  0);
 923static SUNXI_CCU_MUX_HW_WITH_GATE(fanout2_clk, "fanout2", fanout_parents, 0xf3c,
 924                                  6, 3,         /* mux */
 925                                  BIT(23),      /* gate */
 926                                  0);
 927
 928static struct ccu_common *sun20i_d1_ccu_clks[] = {
 929        &pll_cpux_clk.common,
 930        &pll_ddr0_clk.common,
 931        &pll_periph0_4x_clk.common,
 932        &pll_periph0_2x_clk.common,
 933        &pll_periph0_800M_clk.common,
 934        &pll_video0_4x_clk.common,
 935        &pll_video1_4x_clk.common,
 936        &pll_ve_clk.common,
 937        &pll_audio0_4x_clk.common,
 938        &pll_audio1_clk.common,
 939        &pll_audio1_div2_clk.common,
 940        &pll_audio1_div5_clk.common,
 941        &cpux_clk.common,
 942        &cpux_axi_clk.common,
 943        &cpux_apb_clk.common,
 944        &psi_ahb_clk.common,
 945        &apb0_clk.common,
 946        &apb1_clk.common,
 947        &de_clk.common,
 948        &bus_de_clk.common,
 949        &di_clk.common,
 950        &bus_di_clk.common,
 951        &g2d_clk.common,
 952        &bus_g2d_clk.common,
 953        &ce_clk.common,
 954        &bus_ce_clk.common,
 955        &ve_clk.common,
 956        &bus_ve_clk.common,
 957        &bus_dma_clk.common,
 958        &bus_msgbox0_clk.common,
 959        &bus_msgbox1_clk.common,
 960        &bus_msgbox2_clk.common,
 961        &bus_spinlock_clk.common,
 962        &bus_hstimer_clk.common,
 963        &avs_clk.common,
 964        &bus_dbg_clk.common,
 965        &bus_pwm_clk.common,
 966        &bus_iommu_clk.common,
 967        &dram_clk.common,
 968        &mbus_dma_clk.common,
 969        &mbus_ve_clk.common,
 970        &mbus_ce_clk.common,
 971        &mbus_tvin_clk.common,
 972        &mbus_csi_clk.common,
 973        &mbus_g2d_clk.common,
 974        &mbus_riscv_clk.common,
 975        &bus_dram_clk.common,
 976        &mmc0_clk.common,
 977        &mmc1_clk.common,
 978        &mmc2_clk.common,
 979        &bus_mmc0_clk.common,
 980        &bus_mmc1_clk.common,
 981        &bus_mmc2_clk.common,
 982        &bus_uart0_clk.common,
 983        &bus_uart1_clk.common,
 984        &bus_uart2_clk.common,
 985        &bus_uart3_clk.common,
 986        &bus_uart4_clk.common,
 987        &bus_uart5_clk.common,
 988        &bus_i2c0_clk.common,
 989        &bus_i2c1_clk.common,
 990        &bus_i2c2_clk.common,
 991        &bus_i2c3_clk.common,
 992        &spi0_clk.common,
 993        &spi1_clk.common,
 994        &bus_spi0_clk.common,
 995        &bus_spi1_clk.common,
 996        &emac_25M_clk.common,
 997        &bus_emac_clk.common,
 998        &ir_tx_clk.common,
 999        &bus_ir_tx_clk.common,
1000        &bus_gpadc_clk.common,
1001        &bus_ths_clk.common,
1002        &i2s0_clk.common,
1003        &i2s1_clk.common,
1004        &i2s2_clk.common,
1005        &i2s2_asrc_clk.common,
1006        &bus_i2s0_clk.common,
1007        &bus_i2s1_clk.common,
1008        &bus_i2s2_clk.common,
1009        &spdif_tx_clk.common,
1010        &spdif_rx_clk.common,
1011        &bus_spdif_clk.common,
1012        &dmic_clk.common,
1013        &bus_dmic_clk.common,
1014        &audio_dac_clk.common,
1015        &audio_adc_clk.common,
1016        &bus_audio_clk.common,
1017        &usb_ohci0_clk.common,
1018        &usb_ohci1_clk.common,
1019        &bus_ohci0_clk.common,
1020        &bus_ohci1_clk.common,
1021        &bus_ehci0_clk.common,
1022        &bus_ehci1_clk.common,
1023        &bus_otg_clk.common,
1024        &bus_lradc_clk.common,
1025        &bus_dpss_top_clk.common,
1026        &hdmi_24M_clk.common,
1027        &hdmi_cec_32k_clk.common,
1028        &hdmi_cec_clk.common,
1029        &bus_hdmi_clk.common,
1030        &mipi_dsi_clk.common,
1031        &bus_mipi_dsi_clk.common,
1032        &tcon_lcd0_clk.common,
1033        &bus_tcon_lcd0_clk.common,
1034        &tcon_tv_clk.common,
1035        &bus_tcon_tv_clk.common,
1036        &tve_clk.common,
1037        &bus_tve_top_clk.common,
1038        &bus_tve_clk.common,
1039        &tvd_clk.common,
1040        &bus_tvd_top_clk.common,
1041        &bus_tvd_clk.common,
1042        &ledc_clk.common,
1043        &bus_ledc_clk.common,
1044        &csi_top_clk.common,
1045        &csi_mclk_clk.common,
1046        &bus_csi_clk.common,
1047        &tpadc_clk.common,
1048        &bus_tpadc_clk.common,
1049        &bus_tzma_clk.common,
1050        &dsp_clk.common,
1051        &bus_dsp_cfg_clk.common,
1052        &riscv_clk.common,
1053        &riscv_axi_clk.common,
1054        &bus_riscv_cfg_clk.common,
1055        &fanout_24M_clk.common,
1056        &fanout_12M_clk.common,
1057        &fanout_16M_clk.common,
1058        &fanout_25M_clk.common,
1059        &fanout_32k_clk.common,
1060        &fanout_27M_clk.common,
1061        &fanout_pclk_clk.common,
1062        &fanout0_clk.common,
1063        &fanout1_clk.common,
1064        &fanout2_clk.common,
1065};
1066
1067static struct clk_hw_onecell_data sun20i_d1_hw_clks = {
1068        .num    = CLK_NUMBER,
1069        .hws    = {
1070                [CLK_PLL_CPUX]          = &pll_cpux_clk.common.hw,
1071                [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
1072                [CLK_PLL_PERIPH0_4X]    = &pll_periph0_4x_clk.common.hw,
1073                [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.common.hw,
1074                [CLK_PLL_PERIPH0_800M]  = &pll_periph0_800M_clk.common.hw,
1075                [CLK_PLL_PERIPH0]       = &pll_periph0_clk.hw,
1076                [CLK_PLL_PERIPH0_DIV3]  = &pll_periph0_div3_clk.hw,
1077                [CLK_PLL_VIDEO0_4X]     = &pll_video0_4x_clk.common.hw,
1078                [CLK_PLL_VIDEO0_2X]     = &pll_video0_2x_clk.hw,
1079                [CLK_PLL_VIDEO0]        = &pll_video0_clk.hw,
1080                [CLK_PLL_VIDEO1_4X]     = &pll_video1_4x_clk.common.hw,
1081                [CLK_PLL_VIDEO1_2X]     = &pll_video1_2x_clk.hw,
1082                [CLK_PLL_VIDEO1]        = &pll_video1_clk.hw,
1083                [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
1084                [CLK_PLL_AUDIO0_4X]     = &pll_audio0_4x_clk.common.hw,
1085                [CLK_PLL_AUDIO0_2X]     = &pll_audio0_2x_clk.hw,
1086                [CLK_PLL_AUDIO0]        = &pll_audio0_clk.hw,
1087                [CLK_PLL_AUDIO1]        = &pll_audio1_clk.common.hw,
1088                [CLK_PLL_AUDIO1_DIV2]   = &pll_audio1_div2_clk.common.hw,
1089                [CLK_PLL_AUDIO1_DIV5]   = &pll_audio1_div5_clk.common.hw,
1090                [CLK_CPUX]              = &cpux_clk.common.hw,
1091                [CLK_CPUX_AXI]          = &cpux_axi_clk.common.hw,
1092                [CLK_CPUX_APB]          = &cpux_apb_clk.common.hw,
1093                [CLK_PSI_AHB]           = &psi_ahb_clk.common.hw,
1094                [CLK_APB0]              = &apb0_clk.common.hw,
1095                [CLK_APB1]              = &apb1_clk.common.hw,
1096                [CLK_MBUS]              = &mbus_clk.hw,
1097                [CLK_DE]                = &de_clk.common.hw,
1098                [CLK_BUS_DE]            = &bus_de_clk.common.hw,
1099                [CLK_DI]                = &di_clk.common.hw,
1100                [CLK_BUS_DI]            = &bus_di_clk.common.hw,
1101                [CLK_G2D]               = &g2d_clk.common.hw,
1102                [CLK_BUS_G2D]           = &bus_g2d_clk.common.hw,
1103                [CLK_CE]                = &ce_clk.common.hw,
1104                [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
1105                [CLK_VE]                = &ve_clk.common.hw,
1106                [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
1107                [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
1108                [CLK_BUS_MSGBOX0]       = &bus_msgbox0_clk.common.hw,
1109                [CLK_BUS_MSGBOX1]       = &bus_msgbox1_clk.common.hw,
1110                [CLK_BUS_MSGBOX2]       = &bus_msgbox2_clk.common.hw,
1111                [CLK_BUS_SPINLOCK]      = &bus_spinlock_clk.common.hw,
1112                [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
1113                [CLK_AVS]               = &avs_clk.common.hw,
1114                [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
1115                [CLK_BUS_PWM]           = &bus_pwm_clk.common.hw,
1116                [CLK_BUS_IOMMU]         = &bus_iommu_clk.common.hw,
1117                [CLK_DRAM]              = &dram_clk.common.hw,
1118                [CLK_MBUS_DMA]          = &mbus_dma_clk.common.hw,
1119                [CLK_MBUS_VE]           = &mbus_ve_clk.common.hw,
1120                [CLK_MBUS_CE]           = &mbus_ce_clk.common.hw,
1121                [CLK_MBUS_TVIN]         = &mbus_tvin_clk.common.hw,
1122                [CLK_MBUS_CSI]          = &mbus_csi_clk.common.hw,
1123                [CLK_MBUS_G2D]          = &mbus_g2d_clk.common.hw,
1124                [CLK_MBUS_RISCV]        = &mbus_riscv_clk.common.hw,
1125                [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
1126                [CLK_MMC0]              = &mmc0_clk.common.hw,
1127                [CLK_MMC1]              = &mmc1_clk.common.hw,
1128                [CLK_MMC2]              = &mmc2_clk.common.hw,
1129                [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
1130                [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
1131                [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
1132                [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
1133                [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
1134                [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
1135                [CLK_BUS_UART3]         = &bus_uart3_clk.common.hw,
1136                [CLK_BUS_UART4]         = &bus_uart4_clk.common.hw,
1137                [CLK_BUS_UART5]         = &bus_uart5_clk.common.hw,
1138                [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
1139                [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
1140                [CLK_BUS_I2C2]          = &bus_i2c2_clk.common.hw,
1141                [CLK_BUS_I2C3]          = &bus_i2c3_clk.common.hw,
1142                [CLK_SPI0]              = &spi0_clk.common.hw,
1143                [CLK_SPI1]              = &spi1_clk.common.hw,
1144                [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
1145                [CLK_BUS_SPI1]          = &bus_spi1_clk.common.hw,
1146                [CLK_EMAC_25M]          = &emac_25M_clk.common.hw,
1147                [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
1148                [CLK_IR_TX]             = &ir_tx_clk.common.hw,
1149                [CLK_BUS_IR_TX]         = &bus_ir_tx_clk.common.hw,
1150                [CLK_BUS_GPADC]         = &bus_gpadc_clk.common.hw,
1151                [CLK_BUS_THS]           = &bus_ths_clk.common.hw,
1152                [CLK_I2S0]              = &i2s0_clk.common.hw,
1153                [CLK_I2S1]              = &i2s1_clk.common.hw,
1154                [CLK_I2S2]              = &i2s2_clk.common.hw,
1155                [CLK_I2S2_ASRC]         = &i2s2_asrc_clk.common.hw,
1156                [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
1157                [CLK_BUS_I2S1]          = &bus_i2s1_clk.common.hw,
1158                [CLK_BUS_I2S2]          = &bus_i2s2_clk.common.hw,
1159                [CLK_SPDIF_TX]          = &spdif_tx_clk.common.hw,
1160                [CLK_SPDIF_RX]          = &spdif_rx_clk.common.hw,
1161                [CLK_BUS_SPDIF]         = &bus_spdif_clk.common.hw,
1162                [CLK_DMIC]              = &dmic_clk.common.hw,
1163                [CLK_BUS_DMIC]          = &bus_dmic_clk.common.hw,
1164                [CLK_AUDIO_DAC]         = &audio_dac_clk.common.hw,
1165                [CLK_AUDIO_ADC]         = &audio_adc_clk.common.hw,
1166                [CLK_BUS_AUDIO]         = &bus_audio_clk.common.hw,
1167                [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
1168                [CLK_USB_OHCI1]         = &usb_ohci1_clk.common.hw,
1169                [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
1170                [CLK_BUS_OHCI1]         = &bus_ohci1_clk.common.hw,
1171                [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
1172                [CLK_BUS_EHCI1]         = &bus_ehci1_clk.common.hw,
1173                [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
1174                [CLK_BUS_LRADC]         = &bus_lradc_clk.common.hw,
1175                [CLK_BUS_DPSS_TOP]      = &bus_dpss_top_clk.common.hw,
1176                [CLK_HDMI_24M]          = &hdmi_24M_clk.common.hw,
1177                [CLK_HDMI_CEC_32K]      = &hdmi_cec_32k_clk.common.hw,
1178                [CLK_HDMI_CEC]          = &hdmi_cec_clk.common.hw,
1179                [CLK_BUS_HDMI]          = &bus_hdmi_clk.common.hw,
1180                [CLK_MIPI_DSI]          = &mipi_dsi_clk.common.hw,
1181                [CLK_BUS_MIPI_DSI]      = &bus_mipi_dsi_clk.common.hw,
1182                [CLK_TCON_LCD0]         = &tcon_lcd0_clk.common.hw,
1183                [CLK_BUS_TCON_LCD0]     = &bus_tcon_lcd0_clk.common.hw,
1184                [CLK_TCON_TV]           = &tcon_tv_clk.common.hw,
1185                [CLK_BUS_TCON_TV]       = &bus_tcon_tv_clk.common.hw,
1186                [CLK_TVE]               = &tve_clk.common.hw,
1187                [CLK_BUS_TVE_TOP]       = &bus_tve_top_clk.common.hw,
1188                [CLK_BUS_TVE]           = &bus_tve_clk.common.hw,
1189                [CLK_TVD]               = &tvd_clk.common.hw,
1190                [CLK_BUS_TVD_TOP]       = &bus_tvd_top_clk.common.hw,
1191                [CLK_BUS_TVD]           = &bus_tvd_clk.common.hw,
1192                [CLK_LEDC]              = &ledc_clk.common.hw,
1193                [CLK_BUS_LEDC]          = &bus_ledc_clk.common.hw,
1194                [CLK_CSI_TOP]           = &csi_top_clk.common.hw,
1195                [CLK_CSI_MCLK]          = &csi_mclk_clk.common.hw,
1196                [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
1197                [CLK_TPADC]             = &tpadc_clk.common.hw,
1198                [CLK_BUS_TPADC]         = &bus_tpadc_clk.common.hw,
1199                [CLK_BUS_TZMA]          = &bus_tzma_clk.common.hw,
1200                [CLK_DSP]               = &dsp_clk.common.hw,
1201                [CLK_BUS_DSP_CFG]       = &bus_dsp_cfg_clk.common.hw,
1202                [CLK_RISCV]             = &riscv_clk.common.hw,
1203                [CLK_RISCV_AXI]         = &riscv_axi_clk.common.hw,
1204                [CLK_BUS_RISCV_CFG]     = &bus_riscv_cfg_clk.common.hw,
1205                [CLK_FANOUT_24M]        = &fanout_24M_clk.common.hw,
1206                [CLK_FANOUT_12M]        = &fanout_12M_clk.common.hw,
1207                [CLK_FANOUT_16M]        = &fanout_16M_clk.common.hw,
1208                [CLK_FANOUT_25M]        = &fanout_25M_clk.common.hw,
1209                [CLK_FANOUT_32K]        = &fanout_32k_clk.common.hw,
1210                [CLK_FANOUT_27M]        = &fanout_27M_clk.common.hw,
1211                [CLK_FANOUT_PCLK]       = &fanout_pclk_clk.common.hw,
1212                [CLK_FANOUT0]           = &fanout0_clk.common.hw,
1213                [CLK_FANOUT1]           = &fanout1_clk.common.hw,
1214                [CLK_FANOUT2]           = &fanout2_clk.common.hw,
1215        },
1216};
1217
1218static struct ccu_reset_map sun20i_d1_ccu_resets[] = {
1219        [RST_MBUS]              = { 0x540, BIT(30) },
1220        [RST_BUS_DE]            = { 0x60c, BIT(16) },
1221        [RST_BUS_DI]            = { 0x62c, BIT(16) },
1222        [RST_BUS_G2D]           = { 0x63c, BIT(16) },
1223        [RST_BUS_CE]            = { 0x68c, BIT(16) },
1224        [RST_BUS_VE]            = { 0x69c, BIT(16) },
1225        [RST_BUS_DMA]           = { 0x70c, BIT(16) },
1226        [RST_BUS_MSGBOX0]       = { 0x71c, BIT(16) },
1227        [RST_BUS_MSGBOX1]       = { 0x71c, BIT(17) },
1228        [RST_BUS_MSGBOX2]       = { 0x71c, BIT(18) },
1229        [RST_BUS_SPINLOCK]      = { 0x72c, BIT(16) },
1230        [RST_BUS_HSTIMER]       = { 0x73c, BIT(16) },
1231        [RST_BUS_DBG]           = { 0x78c, BIT(16) },
1232        [RST_BUS_PWM]           = { 0x7ac, BIT(16) },
1233        [RST_BUS_DRAM]          = { 0x80c, BIT(16) },
1234        [RST_BUS_MMC0]          = { 0x84c, BIT(16) },
1235        [RST_BUS_MMC1]          = { 0x84c, BIT(17) },
1236        [RST_BUS_MMC2]          = { 0x84c, BIT(18) },
1237        [RST_BUS_UART0]         = { 0x90c, BIT(16) },
1238        [RST_BUS_UART1]         = { 0x90c, BIT(17) },
1239        [RST_BUS_UART2]         = { 0x90c, BIT(18) },
1240        [RST_BUS_UART3]         = { 0x90c, BIT(19) },
1241        [RST_BUS_UART4]         = { 0x90c, BIT(20) },
1242        [RST_BUS_UART5]         = { 0x90c, BIT(21) },
1243        [RST_BUS_I2C0]          = { 0x91c, BIT(16) },
1244        [RST_BUS_I2C1]          = { 0x91c, BIT(17) },
1245        [RST_BUS_I2C2]          = { 0x91c, BIT(18) },
1246        [RST_BUS_I2C3]          = { 0x91c, BIT(19) },
1247        [RST_BUS_SPI0]          = { 0x96c, BIT(16) },
1248        [RST_BUS_SPI1]          = { 0x96c, BIT(17) },
1249        [RST_BUS_EMAC]          = { 0x97c, BIT(16) },
1250        [RST_BUS_IR_TX]         = { 0x9cc, BIT(16) },
1251        [RST_BUS_GPADC]         = { 0x9ec, BIT(16) },
1252        [RST_BUS_THS]           = { 0x9fc, BIT(16) },
1253        [RST_BUS_I2S0]          = { 0xa20, BIT(16) },
1254        [RST_BUS_I2S1]          = { 0xa20, BIT(17) },
1255        [RST_BUS_I2S2]          = { 0xa20, BIT(18) },
1256        [RST_BUS_SPDIF]         = { 0xa2c, BIT(16) },
1257        [RST_BUS_DMIC]          = { 0xa4c, BIT(16) },
1258        [RST_BUS_AUDIO]         = { 0xa5c, BIT(16) },
1259        [RST_USB_PHY0]          = { 0xa70, BIT(30) },
1260        [RST_USB_PHY1]          = { 0xa74, BIT(30) },
1261        [RST_BUS_OHCI0]         = { 0xa8c, BIT(16) },
1262        [RST_BUS_OHCI1]         = { 0xa8c, BIT(17) },
1263        [RST_BUS_EHCI0]         = { 0xa8c, BIT(20) },
1264        [RST_BUS_EHCI1]         = { 0xa8c, BIT(21) },
1265        [RST_BUS_OTG]           = { 0xa8c, BIT(24) },
1266        [RST_BUS_LRADC]         = { 0xa9c, BIT(16) },
1267        [RST_BUS_DPSS_TOP]      = { 0xabc, BIT(16) },
1268        [RST_BUS_HDMI_MAIN]     = { 0xb1c, BIT(16) },
1269        [RST_BUS_HDMI_SUB]      = { 0xb1c, BIT(17) },
1270        [RST_BUS_MIPI_DSI]      = { 0xb4c, BIT(16) },
1271        [RST_BUS_TCON_LCD0]     = { 0xb7c, BIT(16) },
1272        [RST_BUS_TCON_TV]       = { 0xb9c, BIT(16) },
1273        [RST_BUS_LVDS0]         = { 0xbac, BIT(16) },
1274        [RST_BUS_TVE_TOP]       = { 0xbbc, BIT(16) },
1275        [RST_BUS_TVE]           = { 0xbbc, BIT(17) },
1276        [RST_BUS_TVD_TOP]       = { 0xbdc, BIT(16) },
1277        [RST_BUS_TVD]           = { 0xbdc, BIT(17) },
1278        [RST_BUS_LEDC]          = { 0xbfc, BIT(16) },
1279        [RST_BUS_CSI]           = { 0xc1c, BIT(16) },
1280        [RST_BUS_TPADC]         = { 0xc5c, BIT(16) },
1281        [RST_DSP]               = { 0xc7c, BIT(16) },
1282        [RST_BUS_DSP_CFG]       = { 0xc7c, BIT(17) },
1283        [RST_BUS_DSP_DBG]       = { 0xc7c, BIT(18) },
1284        [RST_BUS_RISCV_CFG]     = { 0xd0c, BIT(16) },
1285};
1286
1287static const struct sunxi_ccu_desc sun20i_d1_ccu_desc = {
1288        .ccu_clks       = sun20i_d1_ccu_clks,
1289        .num_ccu_clks   = ARRAY_SIZE(sun20i_d1_ccu_clks),
1290
1291        .hw_clks        = &sun20i_d1_hw_clks,
1292
1293        .resets         = sun20i_d1_ccu_resets,
1294        .num_resets     = ARRAY_SIZE(sun20i_d1_ccu_resets),
1295};
1296
1297static const u32 pll_regs[] = {
1298        SUN20I_D1_PLL_CPUX_REG,
1299        SUN20I_D1_PLL_DDR0_REG,
1300        SUN20I_D1_PLL_PERIPH0_REG,
1301        SUN20I_D1_PLL_VIDEO0_REG,
1302        SUN20I_D1_PLL_VIDEO1_REG,
1303        SUN20I_D1_PLL_VE_REG,
1304        SUN20I_D1_PLL_AUDIO0_REG,
1305        SUN20I_D1_PLL_AUDIO1_REG,
1306};
1307
1308static const u32 pll_video_regs[] = {
1309        SUN20I_D1_PLL_VIDEO0_REG,
1310        SUN20I_D1_PLL_VIDEO1_REG,
1311};
1312
1313static struct ccu_mux_nb sun20i_d1_riscv_nb = {
1314        .common         = &riscv_clk.common,
1315        .cm             = &riscv_clk.mux,
1316        .delay_us       = 1,
1317        .bypass_index   = 4, /* index of pll-periph0 */
1318};
1319
1320static int sun20i_d1_ccu_probe(struct platform_device *pdev)
1321{
1322        void __iomem *reg;
1323        u32 val;
1324        int i, ret;
1325
1326        reg = devm_platform_ioremap_resource(pdev, 0);
1327        if (IS_ERR(reg))
1328                return PTR_ERR(reg);
1329
1330        /* Enable the enable, LDO, and lock bits on all PLLs. */
1331        for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
1332                val = readl(reg + pll_regs[i]);
1333                val |= BIT(31) | BIT(30) | BIT(29);
1334                writel(val, reg + pll_regs[i]);
1335        }
1336
1337        /* Force PLL_CPUX factor M to 0. */
1338        val = readl(reg + SUN20I_D1_PLL_CPUX_REG);
1339        val &= ~GENMASK(1, 0);
1340        writel(val, reg + SUN20I_D1_PLL_CPUX_REG);
1341
1342        /*
1343         * Force the output divider of video PLLs to 0.
1344         *
1345         * See the comment before pll-video0 definition for the reason.
1346         */
1347        for (i = 0; i < ARRAY_SIZE(pll_video_regs); i++) {
1348                val = readl(reg + pll_video_regs[i]);
1349                val &= ~BIT(0);
1350                writel(val, reg + pll_video_regs[i]);
1351        }
1352
1353        /* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */
1354        val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
1355        val &= ~BIT(1) | BIT(0);
1356        writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
1357
1358        /* Force fanout-27M factor N to 0. */
1359        val = readl(reg + SUN20I_D1_FANOUT_27M_REG);
1360        val &= ~GENMASK(9, 8);
1361        writel(val, reg + SUN20I_D1_FANOUT_27M_REG);
1362
1363        ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_ccu_desc);
1364        if (ret)
1365                return ret;
1366
1367        /* Reparent CPU during PLL CPUX rate changes */
1368        ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
1369                                  &sun20i_d1_riscv_nb);
1370
1371        return 0;
1372}
1373
1374static const struct of_device_id sun20i_d1_ccu_ids[] = {
1375        { .compatible = "allwinner,sun20i-d1-ccu" },
1376        { }
1377};
1378
1379static struct platform_driver sun20i_d1_ccu_driver = {
1380        .probe  = sun20i_d1_ccu_probe,
1381        .driver = {
1382                .name                   = "sun20i-d1-ccu",
1383                .suppress_bind_attrs    = true,
1384                .of_match_table         = sun20i_d1_ccu_ids,
1385        },
1386};
1387module_platform_driver(sun20i_d1_ccu_driver);
1388
1389MODULE_IMPORT_NS(SUNXI_CCU);
1390MODULE_LICENSE("GPL");
1391