Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2016 Maxime Ripard. All rights reserved.
0004  */
0005 
0006 #include <linux/clk-provider.h>
0007 #include <linux/io.h>
0008 #include <linux/module.h>
0009 #include <linux/of_device.h>
0010 #include <linux/platform_device.h>
0011 
0012 #include "ccu_common.h"
0013 #include "ccu_reset.h"
0014 
0015 #include "ccu_div.h"
0016 #include "ccu_gate.h"
0017 #include "ccu_mp.h"
0018 #include "ccu_mult.h"
0019 #include "ccu_nk.h"
0020 #include "ccu_nkm.h"
0021 #include "ccu_nkmp.h"
0022 #include "ccu_nm.h"
0023 #include "ccu_phase.h"
0024 #include "ccu_sdm.h"
0025 
0026 #include "ccu-sun8i-h3.h"
0027 
0028 static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux",
0029                      "osc24M", 0x000,
0030                      8, 5,  /* N */
0031                      4, 2,  /* K */
0032                      0, 2,  /* M */
0033                      16, 2, /* P */
0034                      BIT(31),   /* gate */
0035                      BIT(28),   /* lock */
0036                      CLK_SET_RATE_UNGATE);
0037 
0038 /*
0039  * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
0040  * the base (2x, 4x and 8x), and one variable divider (the one true
0041  * pll audio).
0042  *
0043  * With sigma-delta modulation for fractional-N on the audio PLL,
0044  * we have to use specific dividers. This means the variable divider
0045  * can no longer be used, as the audio codec requests the exact clock
0046  * rates we support through this mechanism. So we now hard code the
0047  * variable divider to 1. This means the clock rates will no longer
0048  * match the clock names.
0049  */
0050 #define SUN8I_H3_PLL_AUDIO_REG  0x008
0051 
0052 static struct ccu_sdm_setting pll_audio_sdm_table[] = {
0053     { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
0054     { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
0055 };
0056 
0057 static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
0058                        "osc24M", 0x008,
0059                        8, 7,    /* N */
0060                        0, 5,    /* M */
0061                        pll_audio_sdm_table, BIT(24),
0062                        0x284, BIT(31),
0063                        BIT(31), /* gate */
0064                        BIT(28), /* lock */
0065                        CLK_SET_RATE_UNGATE);
0066 
0067 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video",
0068                         "osc24M", 0x0010,
0069                         192000000, /* Minimum rate */
0070                         912000000, /* Maximum rate */
0071                         8, 7,      /* N */
0072                         0, 4,      /* M */
0073                         BIT(24),   /* frac enable */
0074                         BIT(25),   /* frac select */
0075                         270000000, /* frac rate 0 */
0076                         297000000, /* frac rate 1 */
0077                         BIT(31),   /* gate */
0078                         BIT(28),   /* lock */
0079                         CLK_SET_RATE_UNGATE);
0080 
0081 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
0082                     "osc24M", 0x0018,
0083                     8, 7,       /* N */
0084                     0, 4,       /* M */
0085                     BIT(24),    /* frac enable */
0086                     BIT(25),    /* frac select */
0087                     270000000,  /* frac rate 0 */
0088                     297000000,  /* frac rate 1 */
0089                     BIT(31),    /* gate */
0090                     BIT(28),    /* lock */
0091                     CLK_SET_RATE_UNGATE);
0092 
0093 static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
0094                     "osc24M", 0x020,
0095                     8, 5,   /* N */
0096                     4, 2,   /* K */
0097                     0, 2,   /* M */
0098                     BIT(31),    /* gate */
0099                     BIT(28),    /* lock */
0100                     CLK_SET_RATE_UNGATE);
0101 
0102 static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
0103                        "osc24M", 0x028,
0104                        8, 5,    /* N */
0105                        4, 2,    /* K */
0106                        BIT(31), /* gate */
0107                        BIT(28), /* lock */
0108                        2,       /* post-div */
0109                        CLK_SET_RATE_UNGATE);
0110 
0111 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
0112                     "osc24M", 0x0038,
0113                     8, 7,       /* N */
0114                     0, 4,       /* M */
0115                     BIT(24),    /* frac enable */
0116                     BIT(25),    /* frac select */
0117                     270000000,  /* frac rate 0 */
0118                     297000000,  /* frac rate 1 */
0119                     BIT(31),    /* gate */
0120                     BIT(28),    /* lock */
0121                     CLK_SET_RATE_UNGATE);
0122 
0123 static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
0124                        "osc24M", 0x044,
0125                        8, 5,    /* N */
0126                        4, 2,    /* K */
0127                        BIT(31), /* gate */
0128                        BIT(28), /* lock */
0129                        2,       /* post-div */
0130                        CLK_SET_RATE_UNGATE);
0131 
0132 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
0133                     "osc24M", 0x0048,
0134                     8, 7,       /* N */
0135                     0, 4,       /* M */
0136                     BIT(24),    /* frac enable */
0137                     BIT(25),    /* frac select */
0138                     270000000,  /* frac rate 0 */
0139                     297000000,  /* frac rate 1 */
0140                     BIT(31),    /* gate */
0141                     BIT(28),    /* lock */
0142                     CLK_SET_RATE_UNGATE);
0143 
0144 static const char * const cpux_parents[] = { "osc32k", "osc24M",
0145                          "pll-cpux" , "pll-cpux" };
0146 static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
0147              0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
0148 
0149 static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
0150 
0151 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
0152                          "axi" , "pll-periph0" };
0153 static const struct ccu_mux_var_prediv ahb1_predivs[] = {
0154     { .index = 3, .shift = 6, .width = 2 },
0155 };
0156 static struct ccu_div ahb1_clk = {
0157     .div        = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
0158 
0159     .mux        = {
0160         .shift  = 12,
0161         .width  = 2,
0162 
0163         .var_predivs    = ahb1_predivs,
0164         .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
0165     },
0166 
0167     .common     = {
0168         .reg        = 0x054,
0169         .features   = CCU_FEATURE_VARIABLE_PREDIV,
0170         .hw.init    = CLK_HW_INIT_PARENTS("ahb1",
0171                               ahb1_parents,
0172                               &ccu_div_ops,
0173                               0),
0174     },
0175 };
0176 
0177 static struct clk_div_table apb1_div_table[] = {
0178     { .val = 0, .div = 2 },
0179     { .val = 1, .div = 2 },
0180     { .val = 2, .div = 4 },
0181     { .val = 3, .div = 8 },
0182     { /* Sentinel */ },
0183 };
0184 static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
0185                0x054, 8, 2, apb1_div_table, 0);
0186 
0187 static const char * const apb2_parents[] = { "osc32k", "osc24M",
0188                          "pll-periph0" , "pll-periph0" };
0189 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
0190                  0, 5,  /* M */
0191                  16, 2, /* P */
0192                  24, 2, /* mux */
0193                  0);
0194 
0195 static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" };
0196 static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
0197     { .index = 1, .div = 2 },
0198 };
0199 static struct ccu_mux ahb2_clk = {
0200     .mux        = {
0201         .shift  = 0,
0202         .width  = 1,
0203         .fixed_predivs  = ahb2_fixed_predivs,
0204         .n_predivs  = ARRAY_SIZE(ahb2_fixed_predivs),
0205     },
0206 
0207     .common     = {
0208         .reg        = 0x05c,
0209         .features   = CCU_FEATURE_FIXED_PREDIV,
0210         .hw.init    = CLK_HW_INIT_PARENTS("ahb2",
0211                               ahb2_parents,
0212                               &ccu_mux_ops,
0213                               0),
0214     },
0215 };
0216 
0217 static SUNXI_CCU_GATE(bus_ce_clk,   "bus-ce",   "ahb1",
0218               0x060, BIT(5), 0);
0219 static SUNXI_CCU_GATE(bus_dma_clk,  "bus-dma",  "ahb1",
0220               0x060, BIT(6), 0);
0221 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
0222               0x060, BIT(8), 0);
0223 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
0224               0x060, BIT(9), 0);
0225 static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
0226               0x060, BIT(10), 0);
0227 static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
0228               0x060, BIT(13), 0);
0229 static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
0230               0x060, BIT(14), 0);
0231 static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb2",
0232               0x060, BIT(17), 0);
0233 static SUNXI_CCU_GATE(bus_ts_clk,   "bus-ts",   "ahb1",
0234               0x060, BIT(18), 0);
0235 static SUNXI_CCU_GATE(bus_hstimer_clk,  "bus-hstimer",  "ahb1",
0236               0x060, BIT(19), 0);
0237 static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
0238               0x060, BIT(20), 0);
0239 static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
0240               0x060, BIT(21), 0);
0241 static SUNXI_CCU_GATE(bus_otg_clk,  "bus-otg",  "ahb1",
0242               0x060, BIT(23), 0);
0243 static SUNXI_CCU_GATE(bus_ehci0_clk,    "bus-ehci0",    "ahb1",
0244               0x060, BIT(24), 0);
0245 static SUNXI_CCU_GATE(bus_ehci1_clk,    "bus-ehci1",    "ahb2",
0246               0x060, BIT(25), 0);
0247 static SUNXI_CCU_GATE(bus_ehci2_clk,    "bus-ehci2",    "ahb2",
0248               0x060, BIT(26), 0);
0249 static SUNXI_CCU_GATE(bus_ehci3_clk,    "bus-ehci3",    "ahb2",
0250               0x060, BIT(27), 0);
0251 static SUNXI_CCU_GATE(bus_ohci0_clk,    "bus-ohci0",    "ahb1",
0252               0x060, BIT(28), 0);
0253 static SUNXI_CCU_GATE(bus_ohci1_clk,    "bus-ohci1",    "ahb2",
0254               0x060, BIT(29), 0);
0255 static SUNXI_CCU_GATE(bus_ohci2_clk,    "bus-ohci2",    "ahb2",
0256               0x060, BIT(30), 0);
0257 static SUNXI_CCU_GATE(bus_ohci3_clk,    "bus-ohci3",    "ahb2",
0258               0x060, BIT(31), 0);
0259 
0260 static SUNXI_CCU_GATE(bus_ve_clk,   "bus-ve",   "ahb1",
0261               0x064, BIT(0), 0);
0262 static SUNXI_CCU_GATE(bus_tcon0_clk,    "bus-tcon0",    "ahb1",
0263               0x064, BIT(3), 0);
0264 static SUNXI_CCU_GATE(bus_tcon1_clk,    "bus-tcon1",    "ahb1",
0265               0x064, BIT(4), 0);
0266 static SUNXI_CCU_GATE(bus_deinterlace_clk,  "bus-deinterlace",  "ahb1",
0267               0x064, BIT(5), 0);
0268 static SUNXI_CCU_GATE(bus_csi_clk,  "bus-csi",  "ahb1",
0269               0x064, BIT(8), 0);
0270 static SUNXI_CCU_GATE(bus_tve_clk,  "bus-tve",  "ahb1",
0271               0x064, BIT(9), 0);
0272 static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb1",
0273               0x064, BIT(11), 0);
0274 static SUNXI_CCU_GATE(bus_de_clk,   "bus-de",   "ahb1",
0275               0x064, BIT(12), 0);
0276 static SUNXI_CCU_GATE(bus_gpu_clk,  "bus-gpu",  "ahb1",
0277               0x064, BIT(20), 0);
0278 static SUNXI_CCU_GATE(bus_msgbox_clk,   "bus-msgbox",   "ahb1",
0279               0x064, BIT(21), 0);
0280 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
0281               0x064, BIT(22), 0);
0282 
0283 static SUNXI_CCU_GATE(bus_codec_clk,    "bus-codec",    "apb1",
0284               0x068, BIT(0), 0);
0285 static SUNXI_CCU_GATE(bus_spdif_clk,    "bus-spdif",    "apb1",
0286               0x068, BIT(1), 0);
0287 static SUNXI_CCU_GATE(bus_pio_clk,  "bus-pio",  "apb1",
0288               0x068, BIT(5), 0);
0289 static SUNXI_CCU_GATE(bus_ths_clk,  "bus-ths",  "apb1",
0290               0x068, BIT(8), 0);
0291 static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
0292               0x068, BIT(12), 0);
0293 static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
0294               0x068, BIT(13), 0);
0295 static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1",
0296               0x068, BIT(14), 0);
0297 
0298 static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
0299               0x06c, BIT(0), 0);
0300 static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
0301               0x06c, BIT(1), 0);
0302 static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
0303               0x06c, BIT(2), 0);
0304 static SUNXI_CCU_GATE(bus_uart0_clk,    "bus-uart0",    "apb2",
0305               0x06c, BIT(16), 0);
0306 static SUNXI_CCU_GATE(bus_uart1_clk,    "bus-uart1",    "apb2",
0307               0x06c, BIT(17), 0);
0308 static SUNXI_CCU_GATE(bus_uart2_clk,    "bus-uart2",    "apb2",
0309               0x06c, BIT(18), 0);
0310 static SUNXI_CCU_GATE(bus_uart3_clk,    "bus-uart3",    "apb2",
0311               0x06c, BIT(19), 0);
0312 static SUNXI_CCU_GATE(bus_scr0_clk, "bus-scr0", "apb2",
0313               0x06c, BIT(20), 0);
0314 static SUNXI_CCU_GATE(bus_scr1_clk, "bus-scr1", "apb2",
0315               0x06c, BIT(21), 0);
0316 
0317 static SUNXI_CCU_GATE(bus_ephy_clk, "bus-ephy", "ahb1",
0318               0x070, BIT(0), 0);
0319 static SUNXI_CCU_GATE(bus_dbg_clk,  "bus-dbg",  "ahb1",
0320               0x070, BIT(7), 0);
0321 
0322 static struct clk_div_table ths_div_table[] = {
0323     { .val = 0, .div = 1 },
0324     { .val = 1, .div = 2 },
0325     { .val = 2, .div = 4 },
0326     { .val = 3, .div = 6 },
0327     { /* Sentinel */ },
0328 };
0329 static SUNXI_CCU_DIV_TABLE_WITH_GATE(ths_clk, "ths", "osc24M",
0330                      0x074, 0, 2, ths_div_table, BIT(31), 0);
0331 
0332 static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
0333                              "pll-periph1" };
0334 static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
0335                   0, 4,     /* M */
0336                   16, 2,    /* P */
0337                   24, 2,    /* mux */
0338                   BIT(31),  /* gate */
0339                   0);
0340 
0341 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
0342                   0, 4,     /* M */
0343                   16, 2,    /* P */
0344                   24, 2,    /* mux */
0345                   BIT(31),  /* gate */
0346                   0);
0347 
0348 static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
0349                0x088, 20, 3, 0);
0350 static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
0351                0x088, 8, 3, 0);
0352 
0353 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
0354                   0, 4,     /* M */
0355                   16, 2,    /* P */
0356                   24, 2,    /* mux */
0357                   BIT(31),  /* gate */
0358                   0);
0359 
0360 static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
0361                0x08c, 20, 3, 0);
0362 static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
0363                0x08c, 8, 3, 0);
0364 
0365 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
0366                   0, 4,     /* M */
0367                   16, 2,    /* P */
0368                   24, 2,    /* mux */
0369                   BIT(31),  /* gate */
0370                   0);
0371 
0372 static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
0373                0x090, 20, 3, 0);
0374 static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
0375                0x090, 8, 3, 0);
0376 
0377 static const char * const ts_parents[] = { "osc24M", "pll-periph0", };
0378 static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x098,
0379                   0, 4,     /* M */
0380                   16, 2,    /* P */
0381                   24, 2,    /* mux */
0382                   BIT(31),  /* gate */
0383                   0);
0384 
0385 static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", mod0_default_parents, 0x09c,
0386                   0, 4,     /* M */
0387                   16, 2,    /* P */
0388                   24, 2,    /* mux */
0389                   BIT(31),  /* gate */
0390                   0);
0391 
0392 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
0393                   0, 4,     /* M */
0394                   16, 2,    /* P */
0395                   24, 2,    /* mux */
0396                   BIT(31),  /* gate */
0397                   0);
0398 
0399 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
0400                   0, 4,     /* M */
0401                   16, 2,    /* P */
0402                   24, 2,    /* mux */
0403                   BIT(31),  /* gate */
0404                   0);
0405 
0406 static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
0407                         "pll-audio-2x", "pll-audio" };
0408 static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
0409                    0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0410 
0411 static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
0412                    0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0413 
0414 static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", i2s_parents,
0415                    0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0416 
0417 static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
0418                  0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
0419 
0420 static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
0421               0x0cc, BIT(8), 0);
0422 static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
0423               0x0cc, BIT(9), 0);
0424 static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
0425               0x0cc, BIT(10), 0);
0426 static SUNXI_CCU_GATE(usb_phy3_clk, "usb-phy3", "osc24M",
0427               0x0cc, BIT(11), 0);
0428 static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "osc24M",
0429               0x0cc, BIT(16), 0);
0430 static SUNXI_CCU_GATE(usb_ohci1_clk,    "usb-ohci1",    "osc24M",
0431               0x0cc, BIT(17), 0);
0432 static SUNXI_CCU_GATE(usb_ohci2_clk,    "usb-ohci2",    "osc24M",
0433               0x0cc, BIT(18), 0);
0434 static SUNXI_CCU_GATE(usb_ohci3_clk,    "usb-ohci3",    "osc24M",
0435               0x0cc, BIT(19), 0);
0436 
0437 static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" };
0438 static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
0439                 0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
0440 
0441 static SUNXI_CCU_GATE(dram_ve_clk,  "dram-ve",  "dram",
0442               0x100, BIT(0), 0);
0443 static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram",
0444               0x100, BIT(1), 0);
0445 static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram",
0446               0x100, BIT(2), 0);
0447 static SUNXI_CCU_GATE(dram_ts_clk,  "dram-ts",  "dram",
0448               0x100, BIT(3), 0);
0449 
0450 static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
0451 static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
0452                  0x104, 0, 4, 24, 3, BIT(31),
0453                  CLK_SET_RATE_PARENT);
0454 
0455 static const char * const tcon_parents[] = { "pll-video" };
0456 static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
0457                  0x118, 0, 4, 24, 3, BIT(31),
0458                  CLK_SET_RATE_PARENT);
0459 
0460 static const char * const tve_parents[] = { "pll-de", "pll-periph1" };
0461 static SUNXI_CCU_M_WITH_MUX_GATE(tve_clk, "tve", tve_parents,
0462                  0x120, 0, 4, 24, 3, BIT(31), 0);
0463 
0464 static const char * const deinterlace_parents[] = { "pll-periph0", "pll-periph1" };
0465 static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", deinterlace_parents,
0466                  0x124, 0, 4, 24, 3, BIT(31), 0);
0467 
0468 static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M",
0469               0x130, BIT(31), 0);
0470 
0471 static const char * const csi_sclk_parents[] = { "pll-periph0", "pll-periph1" };
0472 static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents,
0473                  0x134, 16, 4, 24, 3, BIT(31), 0);
0474 
0475 static const char * const csi_mclk_parents[] = { "osc24M", "pll-video", "pll-periph1" };
0476 static SUNXI_CCU_M_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", csi_mclk_parents,
0477                  0x134, 0, 5, 8, 3, BIT(15), 0);
0478 
0479 static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
0480                  0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
0481 
0482 static SUNXI_CCU_GATE(ac_dig_clk,   "ac-dig",   "pll-audio",
0483               0x140, BIT(31), CLK_SET_RATE_PARENT);
0484 static SUNXI_CCU_GATE(avs_clk,      "avs",      "osc24M",
0485               0x144, BIT(31), 0);
0486 
0487 static const char * const hdmi_parents[] = { "pll-video" };
0488 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
0489                  0x150, 0, 4, 24, 2, BIT(31),
0490                  CLK_SET_RATE_PARENT);
0491 
0492 static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M",
0493               0x154, BIT(31), 0);
0494 
0495 static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x", "pll-ddr" };
0496 static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
0497                  0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
0498 
0499 static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
0500                  0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
0501 
0502 static struct ccu_common *sun8i_h3_ccu_clks[] = {
0503     &pll_cpux_clk.common,
0504     &pll_audio_base_clk.common,
0505     &pll_video_clk.common,
0506     &pll_ve_clk.common,
0507     &pll_ddr_clk.common,
0508     &pll_periph0_clk.common,
0509     &pll_gpu_clk.common,
0510     &pll_periph1_clk.common,
0511     &pll_de_clk.common,
0512     &cpux_clk.common,
0513     &axi_clk.common,
0514     &ahb1_clk.common,
0515     &apb1_clk.common,
0516     &apb2_clk.common,
0517     &ahb2_clk.common,
0518     &bus_ce_clk.common,
0519     &bus_dma_clk.common,
0520     &bus_mmc0_clk.common,
0521     &bus_mmc1_clk.common,
0522     &bus_mmc2_clk.common,
0523     &bus_nand_clk.common,
0524     &bus_dram_clk.common,
0525     &bus_emac_clk.common,
0526     &bus_ts_clk.common,
0527     &bus_hstimer_clk.common,
0528     &bus_spi0_clk.common,
0529     &bus_spi1_clk.common,
0530     &bus_otg_clk.common,
0531     &bus_ehci0_clk.common,
0532     &bus_ehci1_clk.common,
0533     &bus_ehci2_clk.common,
0534     &bus_ehci3_clk.common,
0535     &bus_ohci0_clk.common,
0536     &bus_ohci1_clk.common,
0537     &bus_ohci2_clk.common,
0538     &bus_ohci3_clk.common,
0539     &bus_ve_clk.common,
0540     &bus_tcon0_clk.common,
0541     &bus_tcon1_clk.common,
0542     &bus_deinterlace_clk.common,
0543     &bus_csi_clk.common,
0544     &bus_tve_clk.common,
0545     &bus_hdmi_clk.common,
0546     &bus_de_clk.common,
0547     &bus_gpu_clk.common,
0548     &bus_msgbox_clk.common,
0549     &bus_spinlock_clk.common,
0550     &bus_codec_clk.common,
0551     &bus_spdif_clk.common,
0552     &bus_pio_clk.common,
0553     &bus_ths_clk.common,
0554     &bus_i2s0_clk.common,
0555     &bus_i2s1_clk.common,
0556     &bus_i2s2_clk.common,
0557     &bus_i2c0_clk.common,
0558     &bus_i2c1_clk.common,
0559     &bus_i2c2_clk.common,
0560     &bus_uart0_clk.common,
0561     &bus_uart1_clk.common,
0562     &bus_uart2_clk.common,
0563     &bus_uart3_clk.common,
0564     &bus_scr0_clk.common,
0565     &bus_scr1_clk.common,
0566     &bus_ephy_clk.common,
0567     &bus_dbg_clk.common,
0568     &ths_clk.common,
0569     &nand_clk.common,
0570     &mmc0_clk.common,
0571     &mmc0_sample_clk.common,
0572     &mmc0_output_clk.common,
0573     &mmc1_clk.common,
0574     &mmc1_sample_clk.common,
0575     &mmc1_output_clk.common,
0576     &mmc2_clk.common,
0577     &mmc2_sample_clk.common,
0578     &mmc2_output_clk.common,
0579     &ts_clk.common,
0580     &ce_clk.common,
0581     &spi0_clk.common,
0582     &spi1_clk.common,
0583     &i2s0_clk.common,
0584     &i2s1_clk.common,
0585     &i2s2_clk.common,
0586     &spdif_clk.common,
0587     &usb_phy0_clk.common,
0588     &usb_phy1_clk.common,
0589     &usb_phy2_clk.common,
0590     &usb_phy3_clk.common,
0591     &usb_ohci0_clk.common,
0592     &usb_ohci1_clk.common,
0593     &usb_ohci2_clk.common,
0594     &usb_ohci3_clk.common,
0595     &dram_clk.common,
0596     &dram_ve_clk.common,
0597     &dram_csi_clk.common,
0598     &dram_deinterlace_clk.common,
0599     &dram_ts_clk.common,
0600     &de_clk.common,
0601     &tcon_clk.common,
0602     &tve_clk.common,
0603     &deinterlace_clk.common,
0604     &csi_misc_clk.common,
0605     &csi_sclk_clk.common,
0606     &csi_mclk_clk.common,
0607     &ve_clk.common,
0608     &ac_dig_clk.common,
0609     &avs_clk.common,
0610     &hdmi_clk.common,
0611     &hdmi_ddc_clk.common,
0612     &mbus_clk.common,
0613     &gpu_clk.common,
0614 };
0615 
0616 static const struct clk_hw *clk_parent_pll_audio[] = {
0617     &pll_audio_base_clk.common.hw
0618 };
0619 
0620 /* We hardcode the divider to 1 for now */
0621 static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
0622                 clk_parent_pll_audio,
0623                 1, 1, CLK_SET_RATE_PARENT);
0624 static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
0625                 clk_parent_pll_audio,
0626                 2, 1, CLK_SET_RATE_PARENT);
0627 static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
0628                 clk_parent_pll_audio,
0629                 1, 1, CLK_SET_RATE_PARENT);
0630 static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
0631                 clk_parent_pll_audio,
0632                 1, 2, CLK_SET_RATE_PARENT);
0633 static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
0634                &pll_periph0_clk.common.hw,
0635                1, 2, 0);
0636 
0637 static struct clk_hw_onecell_data sun8i_h3_hw_clks = {
0638     .hws    = {
0639         [CLK_PLL_CPUX]      = &pll_cpux_clk.common.hw,
0640         [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
0641         [CLK_PLL_AUDIO]     = &pll_audio_clk.hw,
0642         [CLK_PLL_AUDIO_2X]  = &pll_audio_2x_clk.hw,
0643         [CLK_PLL_AUDIO_4X]  = &pll_audio_4x_clk.hw,
0644         [CLK_PLL_AUDIO_8X]  = &pll_audio_8x_clk.hw,
0645         [CLK_PLL_VIDEO]     = &pll_video_clk.common.hw,
0646         [CLK_PLL_VE]        = &pll_ve_clk.common.hw,
0647         [CLK_PLL_DDR]       = &pll_ddr_clk.common.hw,
0648         [CLK_PLL_PERIPH0]   = &pll_periph0_clk.common.hw,
0649         [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
0650         [CLK_PLL_GPU]       = &pll_gpu_clk.common.hw,
0651         [CLK_PLL_PERIPH1]   = &pll_periph1_clk.common.hw,
0652         [CLK_PLL_DE]        = &pll_de_clk.common.hw,
0653         [CLK_CPUX]      = &cpux_clk.common.hw,
0654         [CLK_AXI]       = &axi_clk.common.hw,
0655         [CLK_AHB1]      = &ahb1_clk.common.hw,
0656         [CLK_APB1]      = &apb1_clk.common.hw,
0657         [CLK_APB2]      = &apb2_clk.common.hw,
0658         [CLK_AHB2]      = &ahb2_clk.common.hw,
0659         [CLK_BUS_CE]        = &bus_ce_clk.common.hw,
0660         [CLK_BUS_DMA]       = &bus_dma_clk.common.hw,
0661         [CLK_BUS_MMC0]      = &bus_mmc0_clk.common.hw,
0662         [CLK_BUS_MMC1]      = &bus_mmc1_clk.common.hw,
0663         [CLK_BUS_MMC2]      = &bus_mmc2_clk.common.hw,
0664         [CLK_BUS_NAND]      = &bus_nand_clk.common.hw,
0665         [CLK_BUS_DRAM]      = &bus_dram_clk.common.hw,
0666         [CLK_BUS_EMAC]      = &bus_emac_clk.common.hw,
0667         [CLK_BUS_TS]        = &bus_ts_clk.common.hw,
0668         [CLK_BUS_HSTIMER]   = &bus_hstimer_clk.common.hw,
0669         [CLK_BUS_SPI0]      = &bus_spi0_clk.common.hw,
0670         [CLK_BUS_SPI1]      = &bus_spi1_clk.common.hw,
0671         [CLK_BUS_OTG]       = &bus_otg_clk.common.hw,
0672         [CLK_BUS_EHCI0]     = &bus_ehci0_clk.common.hw,
0673         [CLK_BUS_EHCI1]     = &bus_ehci1_clk.common.hw,
0674         [CLK_BUS_EHCI2]     = &bus_ehci2_clk.common.hw,
0675         [CLK_BUS_EHCI3]     = &bus_ehci3_clk.common.hw,
0676         [CLK_BUS_OHCI0]     = &bus_ohci0_clk.common.hw,
0677         [CLK_BUS_OHCI1]     = &bus_ohci1_clk.common.hw,
0678         [CLK_BUS_OHCI2]     = &bus_ohci2_clk.common.hw,
0679         [CLK_BUS_OHCI3]     = &bus_ohci3_clk.common.hw,
0680         [CLK_BUS_VE]        = &bus_ve_clk.common.hw,
0681         [CLK_BUS_TCON0]     = &bus_tcon0_clk.common.hw,
0682         [CLK_BUS_TCON1]     = &bus_tcon1_clk.common.hw,
0683         [CLK_BUS_DEINTERLACE]   = &bus_deinterlace_clk.common.hw,
0684         [CLK_BUS_CSI]       = &bus_csi_clk.common.hw,
0685         [CLK_BUS_TVE]       = &bus_tve_clk.common.hw,
0686         [CLK_BUS_HDMI]      = &bus_hdmi_clk.common.hw,
0687         [CLK_BUS_DE]        = &bus_de_clk.common.hw,
0688         [CLK_BUS_GPU]       = &bus_gpu_clk.common.hw,
0689         [CLK_BUS_MSGBOX]    = &bus_msgbox_clk.common.hw,
0690         [CLK_BUS_SPINLOCK]  = &bus_spinlock_clk.common.hw,
0691         [CLK_BUS_CODEC]     = &bus_codec_clk.common.hw,
0692         [CLK_BUS_SPDIF]     = &bus_spdif_clk.common.hw,
0693         [CLK_BUS_PIO]       = &bus_pio_clk.common.hw,
0694         [CLK_BUS_THS]       = &bus_ths_clk.common.hw,
0695         [CLK_BUS_I2S0]      = &bus_i2s0_clk.common.hw,
0696         [CLK_BUS_I2S1]      = &bus_i2s1_clk.common.hw,
0697         [CLK_BUS_I2S2]      = &bus_i2s2_clk.common.hw,
0698         [CLK_BUS_I2C0]      = &bus_i2c0_clk.common.hw,
0699         [CLK_BUS_I2C1]      = &bus_i2c1_clk.common.hw,
0700         [CLK_BUS_I2C2]      = &bus_i2c2_clk.common.hw,
0701         [CLK_BUS_UART0]     = &bus_uart0_clk.common.hw,
0702         [CLK_BUS_UART1]     = &bus_uart1_clk.common.hw,
0703         [CLK_BUS_UART2]     = &bus_uart2_clk.common.hw,
0704         [CLK_BUS_UART3]     = &bus_uart3_clk.common.hw,
0705         [CLK_BUS_SCR0]      = &bus_scr0_clk.common.hw,
0706         [CLK_BUS_EPHY]      = &bus_ephy_clk.common.hw,
0707         [CLK_BUS_DBG]       = &bus_dbg_clk.common.hw,
0708         [CLK_THS]       = &ths_clk.common.hw,
0709         [CLK_NAND]      = &nand_clk.common.hw,
0710         [CLK_MMC0]      = &mmc0_clk.common.hw,
0711         [CLK_MMC0_SAMPLE]   = &mmc0_sample_clk.common.hw,
0712         [CLK_MMC0_OUTPUT]   = &mmc0_output_clk.common.hw,
0713         [CLK_MMC1]      = &mmc1_clk.common.hw,
0714         [CLK_MMC1_SAMPLE]   = &mmc1_sample_clk.common.hw,
0715         [CLK_MMC1_OUTPUT]   = &mmc1_output_clk.common.hw,
0716         [CLK_MMC2]      = &mmc2_clk.common.hw,
0717         [CLK_MMC2_SAMPLE]   = &mmc2_sample_clk.common.hw,
0718         [CLK_MMC2_OUTPUT]   = &mmc2_output_clk.common.hw,
0719         [CLK_TS]        = &ts_clk.common.hw,
0720         [CLK_CE]        = &ce_clk.common.hw,
0721         [CLK_SPI0]      = &spi0_clk.common.hw,
0722         [CLK_SPI1]      = &spi1_clk.common.hw,
0723         [CLK_I2S0]      = &i2s0_clk.common.hw,
0724         [CLK_I2S1]      = &i2s1_clk.common.hw,
0725         [CLK_I2S2]      = &i2s2_clk.common.hw,
0726         [CLK_SPDIF]     = &spdif_clk.common.hw,
0727         [CLK_USB_PHY0]      = &usb_phy0_clk.common.hw,
0728         [CLK_USB_PHY1]      = &usb_phy1_clk.common.hw,
0729         [CLK_USB_PHY2]      = &usb_phy2_clk.common.hw,
0730         [CLK_USB_PHY3]      = &usb_phy3_clk.common.hw,
0731         [CLK_USB_OHCI0]     = &usb_ohci0_clk.common.hw,
0732         [CLK_USB_OHCI1]     = &usb_ohci1_clk.common.hw,
0733         [CLK_USB_OHCI2]     = &usb_ohci2_clk.common.hw,
0734         [CLK_USB_OHCI3]     = &usb_ohci3_clk.common.hw,
0735         [CLK_DRAM]      = &dram_clk.common.hw,
0736         [CLK_DRAM_VE]       = &dram_ve_clk.common.hw,
0737         [CLK_DRAM_CSI]      = &dram_csi_clk.common.hw,
0738         [CLK_DRAM_DEINTERLACE]  = &dram_deinterlace_clk.common.hw,
0739         [CLK_DRAM_TS]       = &dram_ts_clk.common.hw,
0740         [CLK_DE]        = &de_clk.common.hw,
0741         [CLK_TCON0]     = &tcon_clk.common.hw,
0742         [CLK_TVE]       = &tve_clk.common.hw,
0743         [CLK_DEINTERLACE]   = &deinterlace_clk.common.hw,
0744         [CLK_CSI_MISC]      = &csi_misc_clk.common.hw,
0745         [CLK_CSI_SCLK]      = &csi_sclk_clk.common.hw,
0746         [CLK_CSI_MCLK]      = &csi_mclk_clk.common.hw,
0747         [CLK_VE]        = &ve_clk.common.hw,
0748         [CLK_AC_DIG]        = &ac_dig_clk.common.hw,
0749         [CLK_AVS]       = &avs_clk.common.hw,
0750         [CLK_HDMI]      = &hdmi_clk.common.hw,
0751         [CLK_HDMI_DDC]      = &hdmi_ddc_clk.common.hw,
0752         [CLK_MBUS]      = &mbus_clk.common.hw,
0753         [CLK_GPU]       = &gpu_clk.common.hw,
0754     },
0755     .num    = CLK_NUMBER_H3,
0756 };
0757 
0758 static struct clk_hw_onecell_data sun50i_h5_hw_clks = {
0759     .hws    = {
0760         [CLK_PLL_CPUX]      = &pll_cpux_clk.common.hw,
0761         [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
0762         [CLK_PLL_AUDIO]     = &pll_audio_clk.hw,
0763         [CLK_PLL_AUDIO_2X]  = &pll_audio_2x_clk.hw,
0764         [CLK_PLL_AUDIO_4X]  = &pll_audio_4x_clk.hw,
0765         [CLK_PLL_AUDIO_8X]  = &pll_audio_8x_clk.hw,
0766         [CLK_PLL_VIDEO]     = &pll_video_clk.common.hw,
0767         [CLK_PLL_VE]        = &pll_ve_clk.common.hw,
0768         [CLK_PLL_DDR]       = &pll_ddr_clk.common.hw,
0769         [CLK_PLL_PERIPH0]   = &pll_periph0_clk.common.hw,
0770         [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
0771         [CLK_PLL_GPU]       = &pll_gpu_clk.common.hw,
0772         [CLK_PLL_PERIPH1]   = &pll_periph1_clk.common.hw,
0773         [CLK_PLL_DE]        = &pll_de_clk.common.hw,
0774         [CLK_CPUX]      = &cpux_clk.common.hw,
0775         [CLK_AXI]       = &axi_clk.common.hw,
0776         [CLK_AHB1]      = &ahb1_clk.common.hw,
0777         [CLK_APB1]      = &apb1_clk.common.hw,
0778         [CLK_APB2]      = &apb2_clk.common.hw,
0779         [CLK_AHB2]      = &ahb2_clk.common.hw,
0780         [CLK_BUS_CE]        = &bus_ce_clk.common.hw,
0781         [CLK_BUS_DMA]       = &bus_dma_clk.common.hw,
0782         [CLK_BUS_MMC0]      = &bus_mmc0_clk.common.hw,
0783         [CLK_BUS_MMC1]      = &bus_mmc1_clk.common.hw,
0784         [CLK_BUS_MMC2]      = &bus_mmc2_clk.common.hw,
0785         [CLK_BUS_NAND]      = &bus_nand_clk.common.hw,
0786         [CLK_BUS_DRAM]      = &bus_dram_clk.common.hw,
0787         [CLK_BUS_EMAC]      = &bus_emac_clk.common.hw,
0788         [CLK_BUS_TS]        = &bus_ts_clk.common.hw,
0789         [CLK_BUS_HSTIMER]   = &bus_hstimer_clk.common.hw,
0790         [CLK_BUS_SPI0]      = &bus_spi0_clk.common.hw,
0791         [CLK_BUS_SPI1]      = &bus_spi1_clk.common.hw,
0792         [CLK_BUS_OTG]       = &bus_otg_clk.common.hw,
0793         [CLK_BUS_EHCI0]     = &bus_ehci0_clk.common.hw,
0794         [CLK_BUS_EHCI1]     = &bus_ehci1_clk.common.hw,
0795         [CLK_BUS_EHCI2]     = &bus_ehci2_clk.common.hw,
0796         [CLK_BUS_EHCI3]     = &bus_ehci3_clk.common.hw,
0797         [CLK_BUS_OHCI0]     = &bus_ohci0_clk.common.hw,
0798         [CLK_BUS_OHCI1]     = &bus_ohci1_clk.common.hw,
0799         [CLK_BUS_OHCI2]     = &bus_ohci2_clk.common.hw,
0800         [CLK_BUS_OHCI3]     = &bus_ohci3_clk.common.hw,
0801         [CLK_BUS_VE]        = &bus_ve_clk.common.hw,
0802         [CLK_BUS_TCON0]     = &bus_tcon0_clk.common.hw,
0803         [CLK_BUS_TCON1]     = &bus_tcon1_clk.common.hw,
0804         [CLK_BUS_DEINTERLACE]   = &bus_deinterlace_clk.common.hw,
0805         [CLK_BUS_CSI]       = &bus_csi_clk.common.hw,
0806         [CLK_BUS_TVE]       = &bus_tve_clk.common.hw,
0807         [CLK_BUS_HDMI]      = &bus_hdmi_clk.common.hw,
0808         [CLK_BUS_DE]        = &bus_de_clk.common.hw,
0809         [CLK_BUS_GPU]       = &bus_gpu_clk.common.hw,
0810         [CLK_BUS_MSGBOX]    = &bus_msgbox_clk.common.hw,
0811         [CLK_BUS_SPINLOCK]  = &bus_spinlock_clk.common.hw,
0812         [CLK_BUS_CODEC]     = &bus_codec_clk.common.hw,
0813         [CLK_BUS_SPDIF]     = &bus_spdif_clk.common.hw,
0814         [CLK_BUS_PIO]       = &bus_pio_clk.common.hw,
0815         [CLK_BUS_THS]       = &bus_ths_clk.common.hw,
0816         [CLK_BUS_I2S0]      = &bus_i2s0_clk.common.hw,
0817         [CLK_BUS_I2S1]      = &bus_i2s1_clk.common.hw,
0818         [CLK_BUS_I2S2]      = &bus_i2s2_clk.common.hw,
0819         [CLK_BUS_I2C0]      = &bus_i2c0_clk.common.hw,
0820         [CLK_BUS_I2C1]      = &bus_i2c1_clk.common.hw,
0821         [CLK_BUS_I2C2]      = &bus_i2c2_clk.common.hw,
0822         [CLK_BUS_UART0]     = &bus_uart0_clk.common.hw,
0823         [CLK_BUS_UART1]     = &bus_uart1_clk.common.hw,
0824         [CLK_BUS_UART2]     = &bus_uart2_clk.common.hw,
0825         [CLK_BUS_UART3]     = &bus_uart3_clk.common.hw,
0826         [CLK_BUS_SCR0]      = &bus_scr0_clk.common.hw,
0827         [CLK_BUS_SCR1]      = &bus_scr1_clk.common.hw,
0828         [CLK_BUS_EPHY]      = &bus_ephy_clk.common.hw,
0829         [CLK_BUS_DBG]       = &bus_dbg_clk.common.hw,
0830         [CLK_THS]       = &ths_clk.common.hw,
0831         [CLK_NAND]      = &nand_clk.common.hw,
0832         [CLK_MMC0]      = &mmc0_clk.common.hw,
0833         [CLK_MMC1]      = &mmc1_clk.common.hw,
0834         [CLK_MMC2]      = &mmc2_clk.common.hw,
0835         [CLK_TS]        = &ts_clk.common.hw,
0836         [CLK_CE]        = &ce_clk.common.hw,
0837         [CLK_SPI0]      = &spi0_clk.common.hw,
0838         [CLK_SPI1]      = &spi1_clk.common.hw,
0839         [CLK_I2S0]      = &i2s0_clk.common.hw,
0840         [CLK_I2S1]      = &i2s1_clk.common.hw,
0841         [CLK_I2S2]      = &i2s2_clk.common.hw,
0842         [CLK_SPDIF]     = &spdif_clk.common.hw,
0843         [CLK_USB_PHY0]      = &usb_phy0_clk.common.hw,
0844         [CLK_USB_PHY1]      = &usb_phy1_clk.common.hw,
0845         [CLK_USB_PHY2]      = &usb_phy2_clk.common.hw,
0846         [CLK_USB_PHY3]      = &usb_phy3_clk.common.hw,
0847         [CLK_USB_OHCI0]     = &usb_ohci0_clk.common.hw,
0848         [CLK_USB_OHCI1]     = &usb_ohci1_clk.common.hw,
0849         [CLK_USB_OHCI2]     = &usb_ohci2_clk.common.hw,
0850         [CLK_USB_OHCI3]     = &usb_ohci3_clk.common.hw,
0851         [CLK_DRAM]      = &dram_clk.common.hw,
0852         [CLK_DRAM_VE]       = &dram_ve_clk.common.hw,
0853         [CLK_DRAM_CSI]      = &dram_csi_clk.common.hw,
0854         [CLK_DRAM_DEINTERLACE]  = &dram_deinterlace_clk.common.hw,
0855         [CLK_DRAM_TS]       = &dram_ts_clk.common.hw,
0856         [CLK_DE]        = &de_clk.common.hw,
0857         [CLK_TCON0]     = &tcon_clk.common.hw,
0858         [CLK_TVE]       = &tve_clk.common.hw,
0859         [CLK_DEINTERLACE]   = &deinterlace_clk.common.hw,
0860         [CLK_CSI_MISC]      = &csi_misc_clk.common.hw,
0861         [CLK_CSI_SCLK]      = &csi_sclk_clk.common.hw,
0862         [CLK_CSI_MCLK]      = &csi_mclk_clk.common.hw,
0863         [CLK_VE]        = &ve_clk.common.hw,
0864         [CLK_AC_DIG]        = &ac_dig_clk.common.hw,
0865         [CLK_AVS]       = &avs_clk.common.hw,
0866         [CLK_HDMI]      = &hdmi_clk.common.hw,
0867         [CLK_HDMI_DDC]      = &hdmi_ddc_clk.common.hw,
0868         [CLK_MBUS]      = &mbus_clk.common.hw,
0869         [CLK_GPU]       = &gpu_clk.common.hw,
0870     },
0871     .num    = CLK_NUMBER_H5,
0872 };
0873 
0874 static struct ccu_reset_map sun8i_h3_ccu_resets[] = {
0875     [RST_USB_PHY0]      =  { 0x0cc, BIT(0) },
0876     [RST_USB_PHY1]      =  { 0x0cc, BIT(1) },
0877     [RST_USB_PHY2]      =  { 0x0cc, BIT(2) },
0878     [RST_USB_PHY3]      =  { 0x0cc, BIT(3) },
0879 
0880     [RST_MBUS]      =  { 0x0fc, BIT(31) },
0881 
0882     [RST_BUS_CE]        =  { 0x2c0, BIT(5) },
0883     [RST_BUS_DMA]       =  { 0x2c0, BIT(6) },
0884     [RST_BUS_MMC0]      =  { 0x2c0, BIT(8) },
0885     [RST_BUS_MMC1]      =  { 0x2c0, BIT(9) },
0886     [RST_BUS_MMC2]      =  { 0x2c0, BIT(10) },
0887     [RST_BUS_NAND]      =  { 0x2c0, BIT(13) },
0888     [RST_BUS_DRAM]      =  { 0x2c0, BIT(14) },
0889     [RST_BUS_EMAC]      =  { 0x2c0, BIT(17) },
0890     [RST_BUS_TS]        =  { 0x2c0, BIT(18) },
0891     [RST_BUS_HSTIMER]   =  { 0x2c0, BIT(19) },
0892     [RST_BUS_SPI0]      =  { 0x2c0, BIT(20) },
0893     [RST_BUS_SPI1]      =  { 0x2c0, BIT(21) },
0894     [RST_BUS_OTG]       =  { 0x2c0, BIT(23) },
0895     [RST_BUS_EHCI0]     =  { 0x2c0, BIT(24) },
0896     [RST_BUS_EHCI1]     =  { 0x2c0, BIT(25) },
0897     [RST_BUS_EHCI2]     =  { 0x2c0, BIT(26) },
0898     [RST_BUS_EHCI3]     =  { 0x2c0, BIT(27) },
0899     [RST_BUS_OHCI0]     =  { 0x2c0, BIT(28) },
0900     [RST_BUS_OHCI1]     =  { 0x2c0, BIT(29) },
0901     [RST_BUS_OHCI2]     =  { 0x2c0, BIT(30) },
0902     [RST_BUS_OHCI3]     =  { 0x2c0, BIT(31) },
0903 
0904     [RST_BUS_VE]        =  { 0x2c4, BIT(0) },
0905     [RST_BUS_TCON0]     =  { 0x2c4, BIT(3) },
0906     [RST_BUS_TCON1]     =  { 0x2c4, BIT(4) },
0907     [RST_BUS_DEINTERLACE]   =  { 0x2c4, BIT(5) },
0908     [RST_BUS_CSI]       =  { 0x2c4, BIT(8) },
0909     [RST_BUS_TVE]       =  { 0x2c4, BIT(9) },
0910     [RST_BUS_HDMI0]     =  { 0x2c4, BIT(10) },
0911     [RST_BUS_HDMI1]     =  { 0x2c4, BIT(11) },
0912     [RST_BUS_DE]        =  { 0x2c4, BIT(12) },
0913     [RST_BUS_GPU]       =  { 0x2c4, BIT(20) },
0914     [RST_BUS_MSGBOX]    =  { 0x2c4, BIT(21) },
0915     [RST_BUS_SPINLOCK]  =  { 0x2c4, BIT(22) },
0916     [RST_BUS_DBG]       =  { 0x2c4, BIT(31) },
0917 
0918     [RST_BUS_EPHY]      =  { 0x2c8, BIT(2) },
0919 
0920     [RST_BUS_CODEC]     =  { 0x2d0, BIT(0) },
0921     [RST_BUS_SPDIF]     =  { 0x2d0, BIT(1) },
0922     [RST_BUS_THS]       =  { 0x2d0, BIT(8) },
0923     [RST_BUS_I2S0]      =  { 0x2d0, BIT(12) },
0924     [RST_BUS_I2S1]      =  { 0x2d0, BIT(13) },
0925     [RST_BUS_I2S2]      =  { 0x2d0, BIT(14) },
0926 
0927     [RST_BUS_I2C0]      =  { 0x2d8, BIT(0) },
0928     [RST_BUS_I2C1]      =  { 0x2d8, BIT(1) },
0929     [RST_BUS_I2C2]      =  { 0x2d8, BIT(2) },
0930     [RST_BUS_UART0]     =  { 0x2d8, BIT(16) },
0931     [RST_BUS_UART1]     =  { 0x2d8, BIT(17) },
0932     [RST_BUS_UART2]     =  { 0x2d8, BIT(18) },
0933     [RST_BUS_UART3]     =  { 0x2d8, BIT(19) },
0934     [RST_BUS_SCR0]      =  { 0x2d8, BIT(20) },
0935 };
0936 
0937 static struct ccu_reset_map sun50i_h5_ccu_resets[] = {
0938     [RST_USB_PHY0]      =  { 0x0cc, BIT(0) },
0939     [RST_USB_PHY1]      =  { 0x0cc, BIT(1) },
0940     [RST_USB_PHY2]      =  { 0x0cc, BIT(2) },
0941     [RST_USB_PHY3]      =  { 0x0cc, BIT(3) },
0942 
0943     [RST_MBUS]      =  { 0x0fc, BIT(31) },
0944 
0945     [RST_BUS_CE]        =  { 0x2c0, BIT(5) },
0946     [RST_BUS_DMA]       =  { 0x2c0, BIT(6) },
0947     [RST_BUS_MMC0]      =  { 0x2c0, BIT(8) },
0948     [RST_BUS_MMC1]      =  { 0x2c0, BIT(9) },
0949     [RST_BUS_MMC2]      =  { 0x2c0, BIT(10) },
0950     [RST_BUS_NAND]      =  { 0x2c0, BIT(13) },
0951     [RST_BUS_DRAM]      =  { 0x2c0, BIT(14) },
0952     [RST_BUS_EMAC]      =  { 0x2c0, BIT(17) },
0953     [RST_BUS_TS]        =  { 0x2c0, BIT(18) },
0954     [RST_BUS_HSTIMER]   =  { 0x2c0, BIT(19) },
0955     [RST_BUS_SPI0]      =  { 0x2c0, BIT(20) },
0956     [RST_BUS_SPI1]      =  { 0x2c0, BIT(21) },
0957     [RST_BUS_OTG]       =  { 0x2c0, BIT(23) },
0958     [RST_BUS_EHCI0]     =  { 0x2c0, BIT(24) },
0959     [RST_BUS_EHCI1]     =  { 0x2c0, BIT(25) },
0960     [RST_BUS_EHCI2]     =  { 0x2c0, BIT(26) },
0961     [RST_BUS_EHCI3]     =  { 0x2c0, BIT(27) },
0962     [RST_BUS_OHCI0]     =  { 0x2c0, BIT(28) },
0963     [RST_BUS_OHCI1]     =  { 0x2c0, BIT(29) },
0964     [RST_BUS_OHCI2]     =  { 0x2c0, BIT(30) },
0965     [RST_BUS_OHCI3]     =  { 0x2c0, BIT(31) },
0966 
0967     [RST_BUS_VE]        =  { 0x2c4, BIT(0) },
0968     [RST_BUS_TCON0]     =  { 0x2c4, BIT(3) },
0969     [RST_BUS_TCON1]     =  { 0x2c4, BIT(4) },
0970     [RST_BUS_DEINTERLACE]   =  { 0x2c4, BIT(5) },
0971     [RST_BUS_CSI]       =  { 0x2c4, BIT(8) },
0972     [RST_BUS_TVE]       =  { 0x2c4, BIT(9) },
0973     [RST_BUS_HDMI0]     =  { 0x2c4, BIT(10) },
0974     [RST_BUS_HDMI1]     =  { 0x2c4, BIT(11) },
0975     [RST_BUS_DE]        =  { 0x2c4, BIT(12) },
0976     [RST_BUS_GPU]       =  { 0x2c4, BIT(20) },
0977     [RST_BUS_MSGBOX]    =  { 0x2c4, BIT(21) },
0978     [RST_BUS_SPINLOCK]  =  { 0x2c4, BIT(22) },
0979     [RST_BUS_DBG]       =  { 0x2c4, BIT(31) },
0980 
0981     [RST_BUS_EPHY]      =  { 0x2c8, BIT(2) },
0982 
0983     [RST_BUS_CODEC]     =  { 0x2d0, BIT(0) },
0984     [RST_BUS_SPDIF]     =  { 0x2d0, BIT(1) },
0985     [RST_BUS_THS]       =  { 0x2d0, BIT(8) },
0986     [RST_BUS_I2S0]      =  { 0x2d0, BIT(12) },
0987     [RST_BUS_I2S1]      =  { 0x2d0, BIT(13) },
0988     [RST_BUS_I2S2]      =  { 0x2d0, BIT(14) },
0989 
0990     [RST_BUS_I2C0]      =  { 0x2d8, BIT(0) },
0991     [RST_BUS_I2C1]      =  { 0x2d8, BIT(1) },
0992     [RST_BUS_I2C2]      =  { 0x2d8, BIT(2) },
0993     [RST_BUS_UART0]     =  { 0x2d8, BIT(16) },
0994     [RST_BUS_UART1]     =  { 0x2d8, BIT(17) },
0995     [RST_BUS_UART2]     =  { 0x2d8, BIT(18) },
0996     [RST_BUS_UART3]     =  { 0x2d8, BIT(19) },
0997     [RST_BUS_SCR0]      =  { 0x2d8, BIT(20) },
0998     [RST_BUS_SCR1]      =  { 0x2d8, BIT(20) },
0999 };
1000 
1001 static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = {
1002     .ccu_clks   = sun8i_h3_ccu_clks,
1003     .num_ccu_clks   = ARRAY_SIZE(sun8i_h3_ccu_clks),
1004 
1005     .hw_clks    = &sun8i_h3_hw_clks,
1006 
1007     .resets     = sun8i_h3_ccu_resets,
1008     .num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets),
1009 };
1010 
1011 static const struct sunxi_ccu_desc sun50i_h5_ccu_desc = {
1012     .ccu_clks   = sun8i_h3_ccu_clks,
1013     .num_ccu_clks   = ARRAY_SIZE(sun8i_h3_ccu_clks),
1014 
1015     .hw_clks    = &sun50i_h5_hw_clks,
1016 
1017     .resets     = sun50i_h5_ccu_resets,
1018     .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets),
1019 };
1020 
1021 static struct ccu_pll_nb sun8i_h3_pll_cpu_nb = {
1022     .common = &pll_cpux_clk.common,
1023     /* copy from pll_cpux_clk */
1024     .enable = BIT(31),
1025     .lock   = BIT(28),
1026 };
1027 
1028 static struct ccu_mux_nb sun8i_h3_cpu_nb = {
1029     .common     = &cpux_clk.common,
1030     .cm     = &cpux_clk.mux,
1031     .delay_us   = 1, /* > 8 clock cycles at 24 MHz */
1032     .bypass_index   = 1, /* index of 24 MHz oscillator */
1033 };
1034 
1035 static int sun8i_h3_ccu_probe(struct platform_device *pdev)
1036 {
1037     const struct sunxi_ccu_desc *desc;
1038     void __iomem *reg;
1039     int ret;
1040     u32 val;
1041 
1042     desc = of_device_get_match_data(&pdev->dev);
1043     if (!desc)
1044         return -EINVAL;
1045 
1046     reg = devm_platform_ioremap_resource(pdev, 0);
1047     if (IS_ERR(reg))
1048         return PTR_ERR(reg);
1049 
1050     /* Force the PLL-Audio-1x divider to 1 */
1051     val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
1052     val &= ~GENMASK(19, 16);
1053     writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
1054 
1055     ret = devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
1056     if (ret)
1057         return ret;
1058 
1059     /* Gate then ungate PLL CPU after any rate changes */
1060     ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
1061 
1062     /* Reparent CPU during PLL CPU rate changes */
1063     ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
1064                   &sun8i_h3_cpu_nb);
1065 
1066     return 0;
1067 }
1068 
1069 static const struct of_device_id sun8i_h3_ccu_ids[] = {
1070     {
1071         .compatible = "allwinner,sun8i-h3-ccu",
1072         .data = &sun8i_h3_ccu_desc,
1073     },
1074     {
1075         .compatible = "allwinner,sun50i-h5-ccu",
1076         .data = &sun50i_h5_ccu_desc,
1077     },
1078     { }
1079 };
1080 
1081 static struct platform_driver sun8i_h3_ccu_driver = {
1082     .probe  = sun8i_h3_ccu_probe,
1083     .driver = {
1084         .name           = "sun8i-h3-ccu",
1085         .suppress_bind_attrs    = true,
1086         .of_match_table     = sun8i_h3_ccu_ids,
1087     },
1088 };
1089 module_platform_driver(sun8i_h3_ccu_driver);
1090 
1091 MODULE_IMPORT_NS(SUNXI_CCU);
1092 MODULE_LICENSE("GPL");