Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2016 Chen-Yu Tsai
0004  *
0005  * Chen-Yu Tsai <wens@csie.org>
0006  *
0007  * Based on ccu-sun8i-h3.c by Maxime Ripard.
0008  */
0009 
0010 #include <linux/clk-provider.h>
0011 #include <linux/io.h>
0012 #include <linux/module.h>
0013 #include <linux/platform_device.h>
0014 
0015 #include "ccu_common.h"
0016 #include "ccu_reset.h"
0017 
0018 #include "ccu_div.h"
0019 #include "ccu_gate.h"
0020 #include "ccu_mp.h"
0021 #include "ccu_mult.h"
0022 #include "ccu_mux.h"
0023 #include "ccu_nk.h"
0024 #include "ccu_nkm.h"
0025 #include "ccu_nkmp.h"
0026 #include "ccu_nm.h"
0027 #include "ccu_phase.h"
0028 #include "ccu_sdm.h"
0029 
0030 #include "ccu-sun6i-a31.h"
0031 
0032 static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
0033                      "osc24M", 0x000,
0034                      8, 5,  /* N */
0035                      4, 2,  /* K */
0036                      0, 2,  /* M */
0037                      BIT(31),   /* gate */
0038                      BIT(28),   /* lock */
0039                      0);
0040 
0041 /*
0042  * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
0043  * the base (2x, 4x and 8x), and one variable divider (the one true
0044  * pll audio).
0045  *
0046  * With sigma-delta modulation for fractional-N on the audio PLL,
0047  * we have to use specific dividers. This means the variable divider
0048  * can no longer be used, as the audio codec requests the exact clock
0049  * rates we support through this mechanism. So we now hard code the
0050  * variable divider to 1. This means the clock rates will no longer
0051  * match the clock names.
0052  */
0053 #define SUN6I_A31_PLL_AUDIO_REG 0x008
0054 
0055 static struct ccu_sdm_setting pll_audio_sdm_table[] = {
0056     { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
0057     { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
0058 };
0059 
0060 static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
0061                        "osc24M", 0x008,
0062                        8, 7,    /* N */
0063                        0, 5,    /* M */
0064                        pll_audio_sdm_table, BIT(24),
0065                        0x284, BIT(31),
0066                        BIT(31), /* gate */
0067                        BIT(28), /* lock */
0068                        CLK_SET_RATE_UNGATE);
0069 
0070 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
0071                     "osc24M", 0x010,
0072                     8, 7,       /* N */
0073                     0, 4,       /* M */
0074                     BIT(24),    /* frac enable */
0075                     BIT(25),    /* frac select */
0076                     270000000,  /* frac rate 0 */
0077                     297000000,  /* frac rate 1 */
0078                     BIT(31),    /* gate */
0079                     BIT(28),    /* lock */
0080                     CLK_SET_RATE_UNGATE);
0081 
0082 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
0083                     "osc24M", 0x018,
0084                     8, 7,       /* N */
0085                     0, 4,       /* M */
0086                     BIT(24),    /* frac enable */
0087                     BIT(25),    /* frac select */
0088                     270000000,  /* frac rate 0 */
0089                     297000000,  /* frac rate 1 */
0090                     BIT(31),    /* gate */
0091                     BIT(28),    /* lock */
0092                     CLK_SET_RATE_UNGATE);
0093 
0094 static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
0095                     "osc24M", 0x020,
0096                     8, 5,   /* N */
0097                     4, 2,   /* K */
0098                     0, 2,   /* M */
0099                     BIT(31),    /* gate */
0100                     BIT(28),    /* lock */
0101                     CLK_SET_RATE_UNGATE);
0102 
0103 static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
0104                        "osc24M", 0x028,
0105                        8, 5,    /* N */
0106                        4, 2,    /* K */
0107                        BIT(31), /* gate */
0108                        BIT(28), /* lock */
0109                        2,       /* post-div */
0110                        CLK_SET_RATE_UNGATE);
0111 
0112 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
0113                     "osc24M", 0x030,
0114                     8, 7,       /* N */
0115                     0, 4,       /* M */
0116                     BIT(24),    /* frac enable */
0117                     BIT(25),    /* frac select */
0118                     270000000,  /* frac rate 0 */
0119                     297000000,  /* frac rate 1 */
0120                     BIT(31),    /* gate */
0121                     BIT(28),    /* lock */
0122                     CLK_SET_RATE_UNGATE);
0123 
0124 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
0125                     "osc24M", 0x038,
0126                     8, 7,       /* N */
0127                     0, 4,       /* M */
0128                     BIT(24),    /* frac enable */
0129                     BIT(25),    /* frac select */
0130                     270000000,  /* frac rate 0 */
0131                     297000000,  /* frac rate 1 */
0132                     BIT(31),    /* gate */
0133                     BIT(28),    /* lock */
0134                     CLK_SET_RATE_UNGATE);
0135 
0136 /*
0137  * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
0138  *
0139  * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
0140  * integer / fractional clock with switchable multipliers and dividers.
0141  * This is not supported here. We hardcode the PLL to MIPI mode.
0142  */
0143 #define SUN6I_A31_PLL_MIPI_REG  0x040
0144 
0145 static const char * const pll_mipi_parents[] = { "pll-video0", "pll-video1" };
0146 static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(pll_mipi_clk, "pll-mipi",
0147                     pll_mipi_parents, 0x040,
0148                     8, 4,   /* N */
0149                     4, 2,   /* K */
0150                     0, 4,   /* M */
0151                     21, 0,  /* mux */
0152                     BIT(31) | BIT(23) | BIT(22), /* gate */
0153                     BIT(28),    /* lock */
0154                     CLK_SET_RATE_UNGATE);
0155 
0156 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll9_clk, "pll9",
0157                     "osc24M", 0x044,
0158                     8, 7,       /* N */
0159                     0, 4,       /* M */
0160                     BIT(24),    /* frac enable */
0161                     BIT(25),    /* frac select */
0162                     270000000,  /* frac rate 0 */
0163                     297000000,  /* frac rate 1 */
0164                     BIT(31),    /* gate */
0165                     BIT(28),    /* lock */
0166                     CLK_SET_RATE_UNGATE);
0167 
0168 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll10_clk, "pll10",
0169                     "osc24M", 0x048,
0170                     8, 7,       /* N */
0171                     0, 4,       /* M */
0172                     BIT(24),    /* frac enable */
0173                     BIT(25),    /* frac select */
0174                     270000000,  /* frac rate 0 */
0175                     297000000,  /* frac rate 1 */
0176                     BIT(31),    /* gate */
0177                     BIT(28),    /* lock */
0178                     CLK_SET_RATE_UNGATE);
0179 
0180 static const char * const cpux_parents[] = { "osc32k", "osc24M",
0181                          "pll-cpu", "pll-cpu" };
0182 static SUNXI_CCU_MUX(cpu_clk, "cpu", cpux_parents,
0183              0x050, 16, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
0184 
0185 static struct clk_div_table axi_div_table[] = {
0186     { .val = 0, .div = 1 },
0187     { .val = 1, .div = 2 },
0188     { .val = 2, .div = 3 },
0189     { .val = 3, .div = 4 },
0190     { .val = 4, .div = 4 },
0191     { .val = 5, .div = 4 },
0192     { .val = 6, .div = 4 },
0193     { .val = 7, .div = 4 },
0194     { /* Sentinel */ },
0195 };
0196 
0197 static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu",
0198                0x050, 0, 3, axi_div_table, 0);
0199 
0200 #define SUN6I_A31_AHB1_REG  0x054
0201 
0202 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
0203                          "axi", "pll-periph" };
0204 static const struct ccu_mux_var_prediv ahb1_predivs[] = {
0205     { .index = 3, .shift = 6, .width = 2 },
0206 };
0207 
0208 static struct ccu_div ahb1_clk = {
0209     .div        = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
0210 
0211     .mux        = {
0212         .shift  = 12,
0213         .width  = 2,
0214 
0215         .var_predivs    = ahb1_predivs,
0216         .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
0217     },
0218 
0219     .common     = {
0220         .reg        = 0x054,
0221         .features   = CCU_FEATURE_VARIABLE_PREDIV,
0222         .hw.init    = CLK_HW_INIT_PARENTS("ahb1",
0223                               ahb1_parents,
0224                               &ccu_div_ops,
0225                               0),
0226     },
0227 };
0228 
0229 static struct clk_div_table apb1_div_table[] = {
0230     { .val = 0, .div = 2 },
0231     { .val = 1, .div = 2 },
0232     { .val = 2, .div = 4 },
0233     { .val = 3, .div = 8 },
0234     { /* Sentinel */ },
0235 };
0236 
0237 static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
0238                0x054, 8, 2, apb1_div_table, 0);
0239 
0240 static const char * const apb2_parents[] = { "osc32k", "osc24M",
0241                          "pll-periph", "pll-periph" };
0242 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
0243                  0, 5,  /* M */
0244                  16, 2, /* P */
0245                  24, 2, /* mux */
0246                  0);
0247 
0248 static SUNXI_CCU_GATE(ahb1_mipidsi_clk, "ahb1-mipidsi", "ahb1",
0249               0x060, BIT(1), 0);
0250 static SUNXI_CCU_GATE(ahb1_ss_clk,  "ahb1-ss",  "ahb1",
0251               0x060, BIT(5), 0);
0252 static SUNXI_CCU_GATE(ahb1_dma_clk, "ahb1-dma", "ahb1",
0253               0x060, BIT(6), 0);
0254 static SUNXI_CCU_GATE(ahb1_mmc0_clk,    "ahb1-mmc0",    "ahb1",
0255               0x060, BIT(8), 0);
0256 static SUNXI_CCU_GATE(ahb1_mmc1_clk,    "ahb1-mmc1",    "ahb1",
0257               0x060, BIT(9), 0);
0258 static SUNXI_CCU_GATE(ahb1_mmc2_clk,    "ahb1-mmc2",    "ahb1",
0259               0x060, BIT(10), 0);
0260 static SUNXI_CCU_GATE(ahb1_mmc3_clk,    "ahb1-mmc3",    "ahb1",
0261               0x060, BIT(11), 0);
0262 static SUNXI_CCU_GATE(ahb1_nand1_clk,   "ahb1-nand1",   "ahb1",
0263               0x060, BIT(12), 0);
0264 static SUNXI_CCU_GATE(ahb1_nand0_clk,   "ahb1-nand0",   "ahb1",
0265               0x060, BIT(13), 0);
0266 static SUNXI_CCU_GATE(ahb1_sdram_clk,   "ahb1-sdram",   "ahb1",
0267               0x060, BIT(14), 0);
0268 static SUNXI_CCU_GATE(ahb1_emac_clk,    "ahb1-emac",    "ahb1",
0269               0x060, BIT(17), 0);
0270 static SUNXI_CCU_GATE(ahb1_ts_clk,  "ahb1-ts",  "ahb1",
0271               0x060, BIT(18), 0);
0272 static SUNXI_CCU_GATE(ahb1_hstimer_clk, "ahb1-hstimer", "ahb1",
0273               0x060, BIT(19), 0);
0274 static SUNXI_CCU_GATE(ahb1_spi0_clk,    "ahb1-spi0",    "ahb1",
0275               0x060, BIT(20), 0);
0276 static SUNXI_CCU_GATE(ahb1_spi1_clk,    "ahb1-spi1",    "ahb1",
0277               0x060, BIT(21), 0);
0278 static SUNXI_CCU_GATE(ahb1_spi2_clk,    "ahb1-spi2",    "ahb1",
0279               0x060, BIT(22), 0);
0280 static SUNXI_CCU_GATE(ahb1_spi3_clk,    "ahb1-spi3",    "ahb1",
0281               0x060, BIT(23), 0);
0282 static SUNXI_CCU_GATE(ahb1_otg_clk, "ahb1-otg", "ahb1",
0283               0x060, BIT(24), 0);
0284 static SUNXI_CCU_GATE(ahb1_ehci0_clk,   "ahb1-ehci0",   "ahb1",
0285               0x060, BIT(26), 0);
0286 static SUNXI_CCU_GATE(ahb1_ehci1_clk,   "ahb1-ehci1",   "ahb1",
0287               0x060, BIT(27), 0);
0288 static SUNXI_CCU_GATE(ahb1_ohci0_clk,   "ahb1-ohci0",   "ahb1",
0289               0x060, BIT(29), 0);
0290 static SUNXI_CCU_GATE(ahb1_ohci1_clk,   "ahb1-ohci1",   "ahb1",
0291               0x060, BIT(30), 0);
0292 static SUNXI_CCU_GATE(ahb1_ohci2_clk,   "ahb1-ohci2",   "ahb1",
0293               0x060, BIT(31), 0);
0294 
0295 static SUNXI_CCU_GATE(ahb1_ve_clk,  "ahb1-ve",  "ahb1",
0296               0x064, BIT(0), 0);
0297 static SUNXI_CCU_GATE(ahb1_lcd0_clk,    "ahb1-lcd0",    "ahb1",
0298               0x064, BIT(4), 0);
0299 static SUNXI_CCU_GATE(ahb1_lcd1_clk,    "ahb1-lcd1",    "ahb1",
0300               0x064, BIT(5), 0);
0301 static SUNXI_CCU_GATE(ahb1_csi_clk, "ahb1-csi", "ahb1",
0302               0x064, BIT(8), 0);
0303 static SUNXI_CCU_GATE(ahb1_hdmi_clk,    "ahb1-hdmi",    "ahb1",
0304               0x064, BIT(11), 0);
0305 static SUNXI_CCU_GATE(ahb1_be0_clk, "ahb1-be0", "ahb1",
0306               0x064, BIT(12), 0);
0307 static SUNXI_CCU_GATE(ahb1_be1_clk, "ahb1-be1", "ahb1",
0308               0x064, BIT(13), 0);
0309 static SUNXI_CCU_GATE(ahb1_fe0_clk, "ahb1-fe0", "ahb1",
0310               0x064, BIT(14), 0);
0311 static SUNXI_CCU_GATE(ahb1_fe1_clk, "ahb1-fe1", "ahb1",
0312               0x064, BIT(15), 0);
0313 static SUNXI_CCU_GATE(ahb1_mp_clk,  "ahb1-mp",  "ahb1",
0314               0x064, BIT(18), 0);
0315 static SUNXI_CCU_GATE(ahb1_gpu_clk, "ahb1-gpu", "ahb1",
0316               0x064, BIT(20), 0);
0317 static SUNXI_CCU_GATE(ahb1_deu0_clk,    "ahb1-deu0",    "ahb1",
0318               0x064, BIT(23), 0);
0319 static SUNXI_CCU_GATE(ahb1_deu1_clk,    "ahb1-deu1",    "ahb1",
0320               0x064, BIT(24), 0);
0321 static SUNXI_CCU_GATE(ahb1_drc0_clk,    "ahb1-drc0",    "ahb1",
0322               0x064, BIT(25), 0);
0323 static SUNXI_CCU_GATE(ahb1_drc1_clk,    "ahb1-drc1",    "ahb1",
0324               0x064, BIT(26), 0);
0325 
0326 static SUNXI_CCU_GATE(apb1_codec_clk,   "apb1-codec",   "apb1",
0327               0x068, BIT(0), 0);
0328 static SUNXI_CCU_GATE(apb1_spdif_clk,   "apb1-spdif",   "apb1",
0329               0x068, BIT(1), 0);
0330 static SUNXI_CCU_GATE(apb1_digital_mic_clk, "apb1-digital-mic", "apb1",
0331               0x068, BIT(4), 0);
0332 static SUNXI_CCU_GATE(apb1_pio_clk, "apb1-pio", "apb1",
0333               0x068, BIT(5), 0);
0334 static SUNXI_CCU_GATE(apb1_daudio0_clk, "apb1-daudio0", "apb1",
0335               0x068, BIT(12), 0);
0336 static SUNXI_CCU_GATE(apb1_daudio1_clk, "apb1-daudio1", "apb1",
0337               0x068, BIT(13), 0);
0338 
0339 static SUNXI_CCU_GATE(apb2_i2c0_clk,    "apb2-i2c0",    "apb2",
0340               0x06c, BIT(0), 0);
0341 static SUNXI_CCU_GATE(apb2_i2c1_clk,    "apb2-i2c1",    "apb2",
0342               0x06c, BIT(1), 0);
0343 static SUNXI_CCU_GATE(apb2_i2c2_clk,    "apb2-i2c2",    "apb2",
0344               0x06c, BIT(2), 0);
0345 static SUNXI_CCU_GATE(apb2_i2c3_clk,    "apb2-i2c3",    "apb2",
0346               0x06c, BIT(3), 0);
0347 static SUNXI_CCU_GATE(apb2_uart0_clk,   "apb2-uart0",   "apb2",
0348               0x06c, BIT(16), 0);
0349 static SUNXI_CCU_GATE(apb2_uart1_clk,   "apb2-uart1",   "apb2",
0350               0x06c, BIT(17), 0);
0351 static SUNXI_CCU_GATE(apb2_uart2_clk,   "apb2-uart2",   "apb2",
0352               0x06c, BIT(18), 0);
0353 static SUNXI_CCU_GATE(apb2_uart3_clk,   "apb2-uart3",   "apb2",
0354               0x06c, BIT(19), 0);
0355 static SUNXI_CCU_GATE(apb2_uart4_clk,   "apb2-uart4",   "apb2",
0356               0x06c, BIT(20), 0);
0357 static SUNXI_CCU_GATE(apb2_uart5_clk,   "apb2-uart5",   "apb2",
0358               0x06c, BIT(21), 0);
0359 
0360 static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
0361 static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", mod0_default_parents,
0362                   0x080,
0363                   0, 4,     /* M */
0364                   16, 2,    /* P */
0365                   24, 2,    /* mux */
0366                   BIT(31),  /* gate */
0367                   0);
0368 
0369 static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", mod0_default_parents,
0370                   0x084,
0371                   0, 4,     /* M */
0372                   16, 2,    /* P */
0373                   24, 2,    /* mux */
0374                   BIT(31),  /* gate */
0375                   0);
0376 
0377 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
0378                   0x088,
0379                   0, 4,     /* M */
0380                   16, 2,    /* P */
0381                   24, 2,    /* mux */
0382                   BIT(31),  /* gate */
0383                   0);
0384 
0385 static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
0386                0x088, 20, 3, 0);
0387 static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
0388                0x088, 8, 3, 0);
0389 
0390 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
0391                   0x08c,
0392                   0, 4,     /* M */
0393                   16, 2,    /* P */
0394                   24, 2,    /* mux */
0395                   BIT(31),  /* gate */
0396                   0);
0397 
0398 static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
0399                0x08c, 20, 3, 0);
0400 static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
0401                0x08c, 8, 3, 0);
0402 
0403 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
0404                   0x090,
0405                   0, 4,     /* M */
0406                   16, 2,    /* P */
0407                   24, 2,    /* mux */
0408                   BIT(31),  /* gate */
0409                   0);
0410 
0411 static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
0412                0x090, 20, 3, 0);
0413 static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
0414                0x090, 8, 3, 0);
0415 
0416 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents,
0417                   0x094,
0418                   0, 4,     /* M */
0419                   16, 2,    /* P */
0420                   24, 2,    /* mux */
0421                   BIT(31),  /* gate */
0422                   0);
0423 
0424 static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3",
0425                0x094, 20, 3, 0);
0426 static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3",
0427                0x094, 8, 3, 0);
0428 
0429 static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
0430                   0, 4,     /* M */
0431                   16, 2,    /* P */
0432                   24, 2,    /* mux */
0433                   BIT(31),  /* gate */
0434                   0);
0435 
0436 static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
0437                   0, 4,     /* M */
0438                   16, 2,    /* P */
0439                   24, 2,    /* mux */
0440                   BIT(31),  /* gate */
0441                   0);
0442 
0443 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
0444                   0, 4,     /* M */
0445                   16, 2,    /* P */
0446                   24, 2,    /* mux */
0447                   BIT(31),  /* gate */
0448                   0);
0449 
0450 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
0451                   0, 4,     /* M */
0452                   16, 2,    /* P */
0453                   24, 2,    /* mux */
0454                   BIT(31),  /* gate */
0455                   0);
0456 static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
0457                   0, 4,     /* M */
0458                   16, 2,    /* P */
0459                   24, 2,    /* mux */
0460                   BIT(31),  /* gate */
0461                   0);
0462 
0463 static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac,
0464                   0, 4,     /* M */
0465                   16, 2,    /* P */
0466                   24, 2,    /* mux */
0467                   BIT(31),  /* gate */
0468                   0);
0469 
0470 static const char * const daudio_parents[] = { "pll-audio-8x", "pll-audio-4x",
0471                            "pll-audio-2x", "pll-audio" };
0472 static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
0473                    0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0474 static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
0475                    0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0476 
0477 static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", daudio_parents,
0478                    0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0479 
0480 static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
0481               0x0cc, BIT(8), 0);
0482 static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
0483               0x0cc, BIT(9), 0);
0484 static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
0485               0x0cc, BIT(10), 0);
0486 static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "osc24M",
0487               0x0cc, BIT(16), 0);
0488 static SUNXI_CCU_GATE(usb_ohci1_clk,    "usb-ohci1",    "osc24M",
0489               0x0cc, BIT(17), 0);
0490 static SUNXI_CCU_GATE(usb_ohci2_clk,    "usb-ohci2",    "osc24M",
0491               0x0cc, BIT(18), 0);
0492 
0493 /* TODO emac clk not supported yet */
0494 
0495 static const char * const dram_parents[] = { "pll-ddr", "pll-periph" };
0496 static SUNXI_CCU_MP_WITH_MUX_GATE(mdfs_clk, "mdfs", dram_parents, 0x0f0,
0497                   0, 4,     /* M */
0498                   16, 2,    /* P */
0499                   24, 2,    /* mux */
0500                   BIT(31),  /* gate */
0501                   CLK_IS_CRITICAL);
0502 
0503 static SUNXI_CCU_M_WITH_MUX(sdram0_clk, "sdram0", dram_parents,
0504                 0x0f4, 0, 4, 4, 1, CLK_IS_CRITICAL);
0505 static SUNXI_CCU_M_WITH_MUX(sdram1_clk, "sdram1", dram_parents,
0506                 0x0f4, 8, 4, 12, 1, CLK_IS_CRITICAL);
0507 
0508 static SUNXI_CCU_GATE(dram_ve_clk,  "dram-ve",  "mdfs",
0509               0x100, BIT(0), 0);
0510 static SUNXI_CCU_GATE(dram_csi_isp_clk, "dram-csi-isp", "mdfs",
0511               0x100, BIT(1), 0);
0512 static SUNXI_CCU_GATE(dram_ts_clk,  "dram-ts",  "mdfs",
0513               0x100, BIT(3), 0);
0514 static SUNXI_CCU_GATE(dram_drc0_clk,    "dram-drc0",    "mdfs",
0515               0x100, BIT(16), 0);
0516 static SUNXI_CCU_GATE(dram_drc1_clk,    "dram-drc1",    "mdfs",
0517               0x100, BIT(17), 0);
0518 static SUNXI_CCU_GATE(dram_deu0_clk,    "dram-deu0",    "mdfs",
0519               0x100, BIT(18), 0);
0520 static SUNXI_CCU_GATE(dram_deu1_clk,    "dram-deu1",    "mdfs",
0521               0x100, BIT(19), 0);
0522 static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "mdfs",
0523               0x100, BIT(24), 0);
0524 static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "mdfs",
0525               0x100, BIT(25), 0);
0526 static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "mdfs",
0527               0x100, BIT(26), 0);
0528 static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "mdfs",
0529               0x100, BIT(27), 0);
0530 static SUNXI_CCU_GATE(dram_mp_clk,  "dram-mp",  "mdfs",
0531               0x100, BIT(28), 0);
0532 
0533 static const char * const de_parents[] = { "pll-video0", "pll-video1",
0534                        "pll-periph-2x", "pll-gpu",
0535                        "pll9", "pll10" };
0536 static SUNXI_CCU_M_WITH_MUX_GATE(be0_clk, "be0", de_parents,
0537                  0x104, 0, 4, 24, 3, BIT(31), 0);
0538 static SUNXI_CCU_M_WITH_MUX_GATE(be1_clk, "be1", de_parents,
0539                  0x108, 0, 4, 24, 3, BIT(31), 0);
0540 static SUNXI_CCU_M_WITH_MUX_GATE(fe0_clk, "fe0", de_parents,
0541                  0x10c, 0, 4, 24, 3, BIT(31), 0);
0542 static SUNXI_CCU_M_WITH_MUX_GATE(fe1_clk, "fe1", de_parents,
0543                  0x110, 0, 4, 24, 3, BIT(31), 0);
0544 
0545 static const char * const mp_parents[] = { "pll-video0", "pll-video1",
0546                        "pll9", "pll10" };
0547 static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", mp_parents,
0548                  0x114, 0, 4, 24, 3, BIT(31), 0);
0549 
0550 static const char * const lcd_ch0_parents[] = { "pll-video0", "pll-video1",
0551                         "pll-video0-2x",
0552                         "pll-video1-2x", "pll-mipi" };
0553 static SUNXI_CCU_MUX_WITH_GATE(lcd0_ch0_clk, "lcd0-ch0", lcd_ch0_parents,
0554                    0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
0555 static SUNXI_CCU_MUX_WITH_GATE(lcd1_ch0_clk, "lcd1-ch0", lcd_ch0_parents,
0556                    0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
0557 
0558 static const char * const lcd_ch1_parents[] = { "pll-video0", "pll-video1",
0559                         "pll-video0-2x",
0560                         "pll-video1-2x" };
0561 static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents,
0562                  0x12c, 0, 4, 24, 3, BIT(31),
0563                  CLK_SET_RATE_PARENT);
0564 static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents,
0565                  0x130, 0, 4, 24, 3, BIT(31),
0566                  CLK_SET_RATE_PARENT);
0567 
0568 static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1",
0569                          "pll9", "pll10", "pll-mipi",
0570                          "pll-ve" };
0571 static SUNXI_CCU_M_WITH_MUX_GATE(csi0_sclk_clk, "csi0-sclk", csi_sclk_parents,
0572                  0x134, 16, 4, 24, 3, BIT(31), 0);
0573 
0574 static const char * const csi_mclk_parents[] = { "pll-video0", "pll-video1",
0575                          "osc24M" };
0576 static const u8 csi_mclk_table[] = { 0, 1, 5 };
0577 static struct ccu_div csi0_mclk_clk = {
0578     .enable     = BIT(15),
0579     .div        = _SUNXI_CCU_DIV(0, 4),
0580     .mux        = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table),
0581     .common     = {
0582         .reg        = 0x134,
0583         .hw.init    = CLK_HW_INIT_PARENTS("csi0-mclk",
0584                               csi_mclk_parents,
0585                               &ccu_div_ops,
0586                               0),
0587     },
0588 };
0589 
0590 static struct ccu_div csi1_mclk_clk = {
0591     .enable     = BIT(15),
0592     .div        = _SUNXI_CCU_DIV(0, 4),
0593     .mux        = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table),
0594     .common     = {
0595         .reg        = 0x138,
0596         .hw.init    = CLK_HW_INIT_PARENTS("csi1-mclk",
0597                               csi_mclk_parents,
0598                               &ccu_div_ops,
0599                               0),
0600     },
0601 };
0602 
0603 static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
0604                  0x13c, 16, 3, BIT(31), 0);
0605 
0606 static SUNXI_CCU_GATE(codec_clk,    "codec",    "pll-audio",
0607               0x140, BIT(31), CLK_SET_RATE_PARENT);
0608 static SUNXI_CCU_GATE(avs_clk,      "avs",      "osc24M",
0609               0x144, BIT(31), 0);
0610 static SUNXI_CCU_GATE(digital_mic_clk,  "digital-mic",  "pll-audio",
0611               0x148, BIT(31), CLK_SET_RATE_PARENT);
0612 
0613 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
0614                  0x150, 0, 4, 24, 2, BIT(31),
0615                  CLK_SET_RATE_PARENT);
0616 
0617 static SUNXI_CCU_GATE(hdmi_ddc_clk, "ddc", "osc24M", 0x150, BIT(30), 0);
0618 
0619 static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
0620 
0621 static const char * const mbus_parents[] = { "osc24M", "pll-periph",
0622                          "pll-ddr" };
0623 static SUNXI_CCU_MP_WITH_MUX_GATE(mbus0_clk, "mbus0", mbus_parents, 0x15c,
0624                   0, 3,     /* M */
0625                   16, 2,    /* P */
0626                   24, 2,    /* mux */
0627                   BIT(31),  /* gate */
0628                   CLK_IS_CRITICAL);
0629 
0630 static SUNXI_CCU_MP_WITH_MUX_GATE(mbus1_clk, "mbus1", mbus_parents, 0x160,
0631                   0, 3,     /* M */
0632                   16, 2,    /* P */
0633                   24, 2,    /* mux */
0634                   BIT(31),  /* gate */
0635                   CLK_IS_CRITICAL);
0636 
0637 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", lcd_ch1_parents,
0638                  0x168, 16, 3, 24, 2, BIT(31),
0639                  CLK_SET_RATE_PARENT);
0640 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_dphy_clk, "mipi-dsi-dphy",
0641                  lcd_ch1_parents, 0x168, 0, 3, 8, 2,
0642                  BIT(15), CLK_SET_RATE_PARENT);
0643 static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_dphy_clk, "mipi-csi-dphy",
0644                  lcd_ch1_parents, 0x16c, 0, 3, 8, 2,
0645                  BIT(15), 0);
0646 
0647 static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc0_clk, "iep-drc0", de_parents,
0648                  0x180, 0, 3, 24, 2, BIT(31), 0);
0649 static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc1_clk, "iep-drc1", de_parents,
0650                  0x184, 0, 3, 24, 2, BIT(31), 0);
0651 static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu0_clk, "iep-deu0", de_parents,
0652                  0x188, 0, 3, 24, 2, BIT(31), 0);
0653 static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu1_clk, "iep-deu1", de_parents,
0654                  0x18c, 0, 3, 24, 2, BIT(31), 0);
0655 
0656 static const char * const gpu_parents[] = { "pll-gpu", "pll-periph-2x",
0657                         "pll-video0", "pll-video1",
0658                         "pll9", "pll10" };
0659 static const struct ccu_mux_fixed_prediv gpu_predivs[] = {
0660     { .index = 1, .div = 3, },
0661 };
0662 
0663 static struct ccu_div gpu_core_clk = {
0664     .enable     = BIT(31),
0665     .div        = _SUNXI_CCU_DIV(0, 3),
0666     .mux        = {
0667         .shift      = 24,
0668         .width      = 3,
0669         .fixed_predivs  = gpu_predivs,
0670         .n_predivs  = ARRAY_SIZE(gpu_predivs),
0671     },
0672     .common     = {
0673         .reg        = 0x1a0,
0674         .features   = CCU_FEATURE_FIXED_PREDIV,
0675         .hw.init    = CLK_HW_INIT_PARENTS("gpu-core",
0676                               gpu_parents,
0677                               &ccu_div_ops,
0678                               0),
0679     },
0680 };
0681 
0682 static struct ccu_div gpu_memory_clk = {
0683     .enable     = BIT(31),
0684     .div        = _SUNXI_CCU_DIV(0, 3),
0685     .mux        = {
0686         .shift      = 24,
0687         .width      = 3,
0688         .fixed_predivs  = gpu_predivs,
0689         .n_predivs  = ARRAY_SIZE(gpu_predivs),
0690     },
0691     .common     = {
0692         .reg        = 0x1a4,
0693         .features   = CCU_FEATURE_FIXED_PREDIV,
0694         .hw.init    = CLK_HW_INIT_PARENTS("gpu-memory",
0695                               gpu_parents,
0696                               &ccu_div_ops,
0697                               0),
0698     },
0699 };
0700 
0701 static struct ccu_div gpu_hyd_clk = {
0702     .enable     = BIT(31),
0703     .div        = _SUNXI_CCU_DIV(0, 3),
0704     .mux        = {
0705         .shift      = 24,
0706         .width      = 3,
0707         .fixed_predivs  = gpu_predivs,
0708         .n_predivs  = ARRAY_SIZE(gpu_predivs),
0709     },
0710     .common     = {
0711         .reg        = 0x1a8,
0712         .features   = CCU_FEATURE_FIXED_PREDIV,
0713         .hw.init    = CLK_HW_INIT_PARENTS("gpu-hyd",
0714                               gpu_parents,
0715                               &ccu_div_ops,
0716                               0),
0717     },
0718 };
0719 
0720 static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", mod0_default_parents, 0x1b0,
0721                  0, 3,      /* M */
0722                  24, 2,     /* mux */
0723                  BIT(31),   /* gate */
0724                  0);
0725 
0726 static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", mod0_default_parents,
0727                  0x1b0,
0728                  0, 3,      /* M */
0729                  24, 2,     /* mux */
0730                  BIT(31),   /* gate */
0731                  0);
0732 
0733 static const char * const clk_out_parents[] = { "osc24M", "osc32k", "osc24M",
0734                         "axi", "ahb1" };
0735 static const u8 clk_out_table[] = { 0, 1, 2, 11, 13 };
0736 
0737 static const struct ccu_mux_fixed_prediv clk_out_predivs[] = {
0738     { .index = 0, .div = 750, },
0739     { .index = 3, .div = 4, },
0740     { .index = 4, .div = 4, },
0741 };
0742 
0743 static struct ccu_mp out_a_clk = {
0744     .enable     = BIT(31),
0745     .m      = _SUNXI_CCU_DIV(8, 5),
0746     .p      = _SUNXI_CCU_DIV(20, 2),
0747     .mux        = {
0748         .shift      = 24,
0749         .width      = 4,
0750         .table      = clk_out_table,
0751         .fixed_predivs  = clk_out_predivs,
0752         .n_predivs  = ARRAY_SIZE(clk_out_predivs),
0753     },
0754     .common     = {
0755         .reg        = 0x300,
0756         .features   = CCU_FEATURE_FIXED_PREDIV,
0757         .hw.init    = CLK_HW_INIT_PARENTS("out-a",
0758                               clk_out_parents,
0759                               &ccu_mp_ops,
0760                               0),
0761     },
0762 };
0763 
0764 static struct ccu_mp out_b_clk = {
0765     .enable     = BIT(31),
0766     .m      = _SUNXI_CCU_DIV(8, 5),
0767     .p      = _SUNXI_CCU_DIV(20, 2),
0768     .mux        = {
0769         .shift      = 24,
0770         .width      = 4,
0771         .table      = clk_out_table,
0772         .fixed_predivs  = clk_out_predivs,
0773         .n_predivs  = ARRAY_SIZE(clk_out_predivs),
0774     },
0775     .common     = {
0776         .reg        = 0x304,
0777         .features   = CCU_FEATURE_FIXED_PREDIV,
0778         .hw.init    = CLK_HW_INIT_PARENTS("out-b",
0779                               clk_out_parents,
0780                               &ccu_mp_ops,
0781                               0),
0782     },
0783 };
0784 
0785 static struct ccu_mp out_c_clk = {
0786     .enable     = BIT(31),
0787     .m      = _SUNXI_CCU_DIV(8, 5),
0788     .p      = _SUNXI_CCU_DIV(20, 2),
0789     .mux        = {
0790         .shift      = 24,
0791         .width      = 4,
0792         .table      = clk_out_table,
0793         .fixed_predivs  = clk_out_predivs,
0794         .n_predivs  = ARRAY_SIZE(clk_out_predivs),
0795     },
0796     .common     = {
0797         .reg        = 0x308,
0798         .features   = CCU_FEATURE_FIXED_PREDIV,
0799         .hw.init    = CLK_HW_INIT_PARENTS("out-c",
0800                               clk_out_parents,
0801                               &ccu_mp_ops,
0802                               0),
0803     },
0804 };
0805 
0806 static struct ccu_common *sun6i_a31_ccu_clks[] = {
0807     &pll_cpu_clk.common,
0808     &pll_audio_base_clk.common,
0809     &pll_video0_clk.common,
0810     &pll_ve_clk.common,
0811     &pll_ddr_clk.common,
0812     &pll_periph_clk.common,
0813     &pll_video1_clk.common,
0814     &pll_gpu_clk.common,
0815     &pll_mipi_clk.common,
0816     &pll9_clk.common,
0817     &pll10_clk.common,
0818     &cpu_clk.common,
0819     &axi_clk.common,
0820     &ahb1_clk.common,
0821     &apb1_clk.common,
0822     &apb2_clk.common,
0823     &ahb1_mipidsi_clk.common,
0824     &ahb1_ss_clk.common,
0825     &ahb1_dma_clk.common,
0826     &ahb1_mmc0_clk.common,
0827     &ahb1_mmc1_clk.common,
0828     &ahb1_mmc2_clk.common,
0829     &ahb1_mmc3_clk.common,
0830     &ahb1_nand1_clk.common,
0831     &ahb1_nand0_clk.common,
0832     &ahb1_sdram_clk.common,
0833     &ahb1_emac_clk.common,
0834     &ahb1_ts_clk.common,
0835     &ahb1_hstimer_clk.common,
0836     &ahb1_spi0_clk.common,
0837     &ahb1_spi1_clk.common,
0838     &ahb1_spi2_clk.common,
0839     &ahb1_spi3_clk.common,
0840     &ahb1_otg_clk.common,
0841     &ahb1_ehci0_clk.common,
0842     &ahb1_ehci1_clk.common,
0843     &ahb1_ohci0_clk.common,
0844     &ahb1_ohci1_clk.common,
0845     &ahb1_ohci2_clk.common,
0846     &ahb1_ve_clk.common,
0847     &ahb1_lcd0_clk.common,
0848     &ahb1_lcd1_clk.common,
0849     &ahb1_csi_clk.common,
0850     &ahb1_hdmi_clk.common,
0851     &ahb1_be0_clk.common,
0852     &ahb1_be1_clk.common,
0853     &ahb1_fe0_clk.common,
0854     &ahb1_fe1_clk.common,
0855     &ahb1_mp_clk.common,
0856     &ahb1_gpu_clk.common,
0857     &ahb1_deu0_clk.common,
0858     &ahb1_deu1_clk.common,
0859     &ahb1_drc0_clk.common,
0860     &ahb1_drc1_clk.common,
0861     &apb1_codec_clk.common,
0862     &apb1_spdif_clk.common,
0863     &apb1_digital_mic_clk.common,
0864     &apb1_pio_clk.common,
0865     &apb1_daudio0_clk.common,
0866     &apb1_daudio1_clk.common,
0867     &apb2_i2c0_clk.common,
0868     &apb2_i2c1_clk.common,
0869     &apb2_i2c2_clk.common,
0870     &apb2_i2c3_clk.common,
0871     &apb2_uart0_clk.common,
0872     &apb2_uart1_clk.common,
0873     &apb2_uart2_clk.common,
0874     &apb2_uart3_clk.common,
0875     &apb2_uart4_clk.common,
0876     &apb2_uart5_clk.common,
0877     &nand0_clk.common,
0878     &nand1_clk.common,
0879     &mmc0_clk.common,
0880     &mmc0_sample_clk.common,
0881     &mmc0_output_clk.common,
0882     &mmc1_clk.common,
0883     &mmc1_sample_clk.common,
0884     &mmc1_output_clk.common,
0885     &mmc2_clk.common,
0886     &mmc2_sample_clk.common,
0887     &mmc2_output_clk.common,
0888     &mmc3_clk.common,
0889     &mmc3_sample_clk.common,
0890     &mmc3_output_clk.common,
0891     &ts_clk.common,
0892     &ss_clk.common,
0893     &spi0_clk.common,
0894     &spi1_clk.common,
0895     &spi2_clk.common,
0896     &spi3_clk.common,
0897     &daudio0_clk.common,
0898     &daudio1_clk.common,
0899     &spdif_clk.common,
0900     &usb_phy0_clk.common,
0901     &usb_phy1_clk.common,
0902     &usb_phy2_clk.common,
0903     &usb_ohci0_clk.common,
0904     &usb_ohci1_clk.common,
0905     &usb_ohci2_clk.common,
0906     &mdfs_clk.common,
0907     &sdram0_clk.common,
0908     &sdram1_clk.common,
0909     &dram_ve_clk.common,
0910     &dram_csi_isp_clk.common,
0911     &dram_ts_clk.common,
0912     &dram_drc0_clk.common,
0913     &dram_drc1_clk.common,
0914     &dram_deu0_clk.common,
0915     &dram_deu1_clk.common,
0916     &dram_fe0_clk.common,
0917     &dram_fe1_clk.common,
0918     &dram_be0_clk.common,
0919     &dram_be1_clk.common,
0920     &dram_mp_clk.common,
0921     &be0_clk.common,
0922     &be1_clk.common,
0923     &fe0_clk.common,
0924     &fe1_clk.common,
0925     &mp_clk.common,
0926     &lcd0_ch0_clk.common,
0927     &lcd1_ch0_clk.common,
0928     &lcd0_ch1_clk.common,
0929     &lcd1_ch1_clk.common,
0930     &csi0_sclk_clk.common,
0931     &csi0_mclk_clk.common,
0932     &csi1_mclk_clk.common,
0933     &ve_clk.common,
0934     &codec_clk.common,
0935     &avs_clk.common,
0936     &digital_mic_clk.common,
0937     &hdmi_clk.common,
0938     &hdmi_ddc_clk.common,
0939     &ps_clk.common,
0940     &mbus0_clk.common,
0941     &mbus1_clk.common,
0942     &mipi_dsi_clk.common,
0943     &mipi_dsi_dphy_clk.common,
0944     &mipi_csi_dphy_clk.common,
0945     &iep_drc0_clk.common,
0946     &iep_drc1_clk.common,
0947     &iep_deu0_clk.common,
0948     &iep_deu1_clk.common,
0949     &gpu_core_clk.common,
0950     &gpu_memory_clk.common,
0951     &gpu_hyd_clk.common,
0952     &ats_clk.common,
0953     &trace_clk.common,
0954     &out_a_clk.common,
0955     &out_b_clk.common,
0956     &out_c_clk.common,
0957 };
0958 
0959 static const struct clk_hw *clk_parent_pll_audio[] = {
0960     &pll_audio_base_clk.common.hw
0961 };
0962 
0963 /* We hardcode the divider to 1 for now */
0964 static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
0965                 clk_parent_pll_audio,
0966                 1, 1, CLK_SET_RATE_PARENT);
0967 static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
0968                 clk_parent_pll_audio,
0969                 2, 1, CLK_SET_RATE_PARENT);
0970 static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
0971                 clk_parent_pll_audio,
0972                 1, 1, CLK_SET_RATE_PARENT);
0973 static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
0974                 clk_parent_pll_audio,
0975                 1, 2, CLK_SET_RATE_PARENT);
0976 static CLK_FIXED_FACTOR_HW(pll_periph_2x_clk, "pll-periph-2x",
0977                &pll_periph_clk.common.hw,
0978                1, 2, 0);
0979 static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
0980                &pll_video0_clk.common.hw,
0981                1, 2, CLK_SET_RATE_PARENT);
0982 static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x",
0983                &pll_video1_clk.common.hw,
0984                1, 2, CLK_SET_RATE_PARENT);
0985 
0986 static struct clk_hw_onecell_data sun6i_a31_hw_clks = {
0987     .hws    = {
0988         [CLK_PLL_CPU]       = &pll_cpu_clk.common.hw,
0989         [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
0990         [CLK_PLL_AUDIO]     = &pll_audio_clk.hw,
0991         [CLK_PLL_AUDIO_2X]  = &pll_audio_2x_clk.hw,
0992         [CLK_PLL_AUDIO_4X]  = &pll_audio_4x_clk.hw,
0993         [CLK_PLL_AUDIO_8X]  = &pll_audio_8x_clk.hw,
0994         [CLK_PLL_VIDEO0]    = &pll_video0_clk.common.hw,
0995         [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
0996         [CLK_PLL_VE]        = &pll_ve_clk.common.hw,
0997         [CLK_PLL_DDR]       = &pll_ddr_clk.common.hw,
0998         [CLK_PLL_PERIPH]    = &pll_periph_clk.common.hw,
0999         [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
1000         [CLK_PLL_VIDEO1]    = &pll_video1_clk.common.hw,
1001         [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
1002         [CLK_PLL_GPU]       = &pll_gpu_clk.common.hw,
1003         [CLK_PLL_MIPI]      = &pll_mipi_clk.common.hw,
1004         [CLK_PLL9]      = &pll9_clk.common.hw,
1005         [CLK_PLL10]     = &pll10_clk.common.hw,
1006         [CLK_CPU]       = &cpu_clk.common.hw,
1007         [CLK_AXI]       = &axi_clk.common.hw,
1008         [CLK_AHB1]      = &ahb1_clk.common.hw,
1009         [CLK_APB1]      = &apb1_clk.common.hw,
1010         [CLK_APB2]      = &apb2_clk.common.hw,
1011         [CLK_AHB1_MIPIDSI]  = &ahb1_mipidsi_clk.common.hw,
1012         [CLK_AHB1_SS]       = &ahb1_ss_clk.common.hw,
1013         [CLK_AHB1_DMA]      = &ahb1_dma_clk.common.hw,
1014         [CLK_AHB1_MMC0]     = &ahb1_mmc0_clk.common.hw,
1015         [CLK_AHB1_MMC1]     = &ahb1_mmc1_clk.common.hw,
1016         [CLK_AHB1_MMC2]     = &ahb1_mmc2_clk.common.hw,
1017         [CLK_AHB1_MMC3]     = &ahb1_mmc3_clk.common.hw,
1018         [CLK_AHB1_NAND1]    = &ahb1_nand1_clk.common.hw,
1019         [CLK_AHB1_NAND0]    = &ahb1_nand0_clk.common.hw,
1020         [CLK_AHB1_SDRAM]    = &ahb1_sdram_clk.common.hw,
1021         [CLK_AHB1_EMAC]     = &ahb1_emac_clk.common.hw,
1022         [CLK_AHB1_TS]       = &ahb1_ts_clk.common.hw,
1023         [CLK_AHB1_HSTIMER]  = &ahb1_hstimer_clk.common.hw,
1024         [CLK_AHB1_SPI0]     = &ahb1_spi0_clk.common.hw,
1025         [CLK_AHB1_SPI1]     = &ahb1_spi1_clk.common.hw,
1026         [CLK_AHB1_SPI2]     = &ahb1_spi2_clk.common.hw,
1027         [CLK_AHB1_SPI3]     = &ahb1_spi3_clk.common.hw,
1028         [CLK_AHB1_OTG]      = &ahb1_otg_clk.common.hw,
1029         [CLK_AHB1_EHCI0]    = &ahb1_ehci0_clk.common.hw,
1030         [CLK_AHB1_EHCI1]    = &ahb1_ehci1_clk.common.hw,
1031         [CLK_AHB1_OHCI0]    = &ahb1_ohci0_clk.common.hw,
1032         [CLK_AHB1_OHCI1]    = &ahb1_ohci1_clk.common.hw,
1033         [CLK_AHB1_OHCI2]    = &ahb1_ohci2_clk.common.hw,
1034         [CLK_AHB1_VE]       = &ahb1_ve_clk.common.hw,
1035         [CLK_AHB1_LCD0]     = &ahb1_lcd0_clk.common.hw,
1036         [CLK_AHB1_LCD1]     = &ahb1_lcd1_clk.common.hw,
1037         [CLK_AHB1_CSI]      = &ahb1_csi_clk.common.hw,
1038         [CLK_AHB1_HDMI]     = &ahb1_hdmi_clk.common.hw,
1039         [CLK_AHB1_BE0]      = &ahb1_be0_clk.common.hw,
1040         [CLK_AHB1_BE1]      = &ahb1_be1_clk.common.hw,
1041         [CLK_AHB1_FE0]      = &ahb1_fe0_clk.common.hw,
1042         [CLK_AHB1_FE1]      = &ahb1_fe1_clk.common.hw,
1043         [CLK_AHB1_MP]       = &ahb1_mp_clk.common.hw,
1044         [CLK_AHB1_GPU]      = &ahb1_gpu_clk.common.hw,
1045         [CLK_AHB1_DEU0]     = &ahb1_deu0_clk.common.hw,
1046         [CLK_AHB1_DEU1]     = &ahb1_deu1_clk.common.hw,
1047         [CLK_AHB1_DRC0]     = &ahb1_drc0_clk.common.hw,
1048         [CLK_AHB1_DRC1]     = &ahb1_drc1_clk.common.hw,
1049         [CLK_APB1_CODEC]    = &apb1_codec_clk.common.hw,
1050         [CLK_APB1_SPDIF]    = &apb1_spdif_clk.common.hw,
1051         [CLK_APB1_DIGITAL_MIC]  = &apb1_digital_mic_clk.common.hw,
1052         [CLK_APB1_PIO]      = &apb1_pio_clk.common.hw,
1053         [CLK_APB1_DAUDIO0]  = &apb1_daudio0_clk.common.hw,
1054         [CLK_APB1_DAUDIO1]  = &apb1_daudio1_clk.common.hw,
1055         [CLK_APB2_I2C0]     = &apb2_i2c0_clk.common.hw,
1056         [CLK_APB2_I2C1]     = &apb2_i2c1_clk.common.hw,
1057         [CLK_APB2_I2C2]     = &apb2_i2c2_clk.common.hw,
1058         [CLK_APB2_I2C3]     = &apb2_i2c3_clk.common.hw,
1059         [CLK_APB2_UART0]    = &apb2_uart0_clk.common.hw,
1060         [CLK_APB2_UART1]    = &apb2_uart1_clk.common.hw,
1061         [CLK_APB2_UART2]    = &apb2_uart2_clk.common.hw,
1062         [CLK_APB2_UART3]    = &apb2_uart3_clk.common.hw,
1063         [CLK_APB2_UART4]    = &apb2_uart4_clk.common.hw,
1064         [CLK_APB2_UART5]    = &apb2_uart5_clk.common.hw,
1065         [CLK_NAND0]     = &nand0_clk.common.hw,
1066         [CLK_NAND1]     = &nand1_clk.common.hw,
1067         [CLK_MMC0]      = &mmc0_clk.common.hw,
1068         [CLK_MMC0_SAMPLE]   = &mmc0_sample_clk.common.hw,
1069         [CLK_MMC0_OUTPUT]   = &mmc0_output_clk.common.hw,
1070         [CLK_MMC1]      = &mmc1_clk.common.hw,
1071         [CLK_MMC1_SAMPLE]   = &mmc1_sample_clk.common.hw,
1072         [CLK_MMC1_OUTPUT]   = &mmc1_output_clk.common.hw,
1073         [CLK_MMC2]      = &mmc2_clk.common.hw,
1074         [CLK_MMC2_SAMPLE]   = &mmc2_sample_clk.common.hw,
1075         [CLK_MMC2_OUTPUT]   = &mmc2_output_clk.common.hw,
1076         [CLK_MMC3]      = &mmc3_clk.common.hw,
1077         [CLK_MMC3_SAMPLE]   = &mmc3_sample_clk.common.hw,
1078         [CLK_MMC3_OUTPUT]   = &mmc3_output_clk.common.hw,
1079         [CLK_TS]        = &ts_clk.common.hw,
1080         [CLK_SS]        = &ss_clk.common.hw,
1081         [CLK_SPI0]      = &spi0_clk.common.hw,
1082         [CLK_SPI1]      = &spi1_clk.common.hw,
1083         [CLK_SPI2]      = &spi2_clk.common.hw,
1084         [CLK_SPI3]      = &spi3_clk.common.hw,
1085         [CLK_DAUDIO0]       = &daudio0_clk.common.hw,
1086         [CLK_DAUDIO1]       = &daudio1_clk.common.hw,
1087         [CLK_SPDIF]     = &spdif_clk.common.hw,
1088         [CLK_USB_PHY0]      = &usb_phy0_clk.common.hw,
1089         [CLK_USB_PHY1]      = &usb_phy1_clk.common.hw,
1090         [CLK_USB_PHY2]      = &usb_phy2_clk.common.hw,
1091         [CLK_USB_OHCI0]     = &usb_ohci0_clk.common.hw,
1092         [CLK_USB_OHCI1]     = &usb_ohci1_clk.common.hw,
1093         [CLK_USB_OHCI2]     = &usb_ohci2_clk.common.hw,
1094         [CLK_MDFS]      = &mdfs_clk.common.hw,
1095         [CLK_SDRAM0]        = &sdram0_clk.common.hw,
1096         [CLK_SDRAM1]        = &sdram1_clk.common.hw,
1097         [CLK_DRAM_VE]       = &dram_ve_clk.common.hw,
1098         [CLK_DRAM_CSI_ISP]  = &dram_csi_isp_clk.common.hw,
1099         [CLK_DRAM_TS]       = &dram_ts_clk.common.hw,
1100         [CLK_DRAM_DRC0]     = &dram_drc0_clk.common.hw,
1101         [CLK_DRAM_DRC1]     = &dram_drc1_clk.common.hw,
1102         [CLK_DRAM_DEU0]     = &dram_deu0_clk.common.hw,
1103         [CLK_DRAM_DEU1]     = &dram_deu1_clk.common.hw,
1104         [CLK_DRAM_FE0]      = &dram_fe0_clk.common.hw,
1105         [CLK_DRAM_FE1]      = &dram_fe1_clk.common.hw,
1106         [CLK_DRAM_BE0]      = &dram_be0_clk.common.hw,
1107         [CLK_DRAM_BE1]      = &dram_be1_clk.common.hw,
1108         [CLK_DRAM_MP]       = &dram_mp_clk.common.hw,
1109         [CLK_BE0]       = &be0_clk.common.hw,
1110         [CLK_BE1]       = &be1_clk.common.hw,
1111         [CLK_FE0]       = &fe0_clk.common.hw,
1112         [CLK_FE1]       = &fe1_clk.common.hw,
1113         [CLK_MP]        = &mp_clk.common.hw,
1114         [CLK_LCD0_CH0]      = &lcd0_ch0_clk.common.hw,
1115         [CLK_LCD1_CH0]      = &lcd1_ch0_clk.common.hw,
1116         [CLK_LCD0_CH1]      = &lcd0_ch1_clk.common.hw,
1117         [CLK_LCD1_CH1]      = &lcd1_ch1_clk.common.hw,
1118         [CLK_CSI0_SCLK]     = &csi0_sclk_clk.common.hw,
1119         [CLK_CSI0_MCLK]     = &csi0_mclk_clk.common.hw,
1120         [CLK_CSI1_MCLK]     = &csi1_mclk_clk.common.hw,
1121         [CLK_VE]        = &ve_clk.common.hw,
1122         [CLK_CODEC]     = &codec_clk.common.hw,
1123         [CLK_AVS]       = &avs_clk.common.hw,
1124         [CLK_DIGITAL_MIC]   = &digital_mic_clk.common.hw,
1125         [CLK_HDMI]      = &hdmi_clk.common.hw,
1126         [CLK_HDMI_DDC]      = &hdmi_ddc_clk.common.hw,
1127         [CLK_PS]        = &ps_clk.common.hw,
1128         [CLK_MBUS0]     = &mbus0_clk.common.hw,
1129         [CLK_MBUS1]     = &mbus1_clk.common.hw,
1130         [CLK_MIPI_DSI]      = &mipi_dsi_clk.common.hw,
1131         [CLK_MIPI_DSI_DPHY] = &mipi_dsi_dphy_clk.common.hw,
1132         [CLK_MIPI_CSI_DPHY] = &mipi_csi_dphy_clk.common.hw,
1133         [CLK_IEP_DRC0]      = &iep_drc0_clk.common.hw,
1134         [CLK_IEP_DRC1]      = &iep_drc1_clk.common.hw,
1135         [CLK_IEP_DEU0]      = &iep_deu0_clk.common.hw,
1136         [CLK_IEP_DEU1]      = &iep_deu1_clk.common.hw,
1137         [CLK_GPU_CORE]      = &gpu_core_clk.common.hw,
1138         [CLK_GPU_MEMORY]    = &gpu_memory_clk.common.hw,
1139         [CLK_GPU_HYD]       = &gpu_hyd_clk.common.hw,
1140         [CLK_ATS]       = &ats_clk.common.hw,
1141         [CLK_TRACE]     = &trace_clk.common.hw,
1142         [CLK_OUT_A]     = &out_a_clk.common.hw,
1143         [CLK_OUT_B]     = &out_b_clk.common.hw,
1144         [CLK_OUT_C]     = &out_c_clk.common.hw,
1145     },
1146     .num    = CLK_NUMBER,
1147 };
1148 
1149 static struct ccu_reset_map sun6i_a31_ccu_resets[] = {
1150     [RST_USB_PHY0]      = { 0x0cc, BIT(0) },
1151     [RST_USB_PHY1]      = { 0x0cc, BIT(1) },
1152     [RST_USB_PHY2]      = { 0x0cc, BIT(2) },
1153 
1154     [RST_AHB1_MIPI_DSI] = { 0x2c0, BIT(1) },
1155     [RST_AHB1_SS]       = { 0x2c0, BIT(5) },
1156     [RST_AHB1_DMA]      = { 0x2c0, BIT(6) },
1157     [RST_AHB1_MMC0]     = { 0x2c0, BIT(8) },
1158     [RST_AHB1_MMC1]     = { 0x2c0, BIT(9) },
1159     [RST_AHB1_MMC2]     = { 0x2c0, BIT(10) },
1160     [RST_AHB1_MMC3]     = { 0x2c0, BIT(11) },
1161     [RST_AHB1_NAND1]    = { 0x2c0, BIT(12) },
1162     [RST_AHB1_NAND0]    = { 0x2c0, BIT(13) },
1163     [RST_AHB1_SDRAM]    = { 0x2c0, BIT(14) },
1164     [RST_AHB1_EMAC]     = { 0x2c0, BIT(17) },
1165     [RST_AHB1_TS]       = { 0x2c0, BIT(18) },
1166     [RST_AHB1_HSTIMER]  = { 0x2c0, BIT(19) },
1167     [RST_AHB1_SPI0]     = { 0x2c0, BIT(20) },
1168     [RST_AHB1_SPI1]     = { 0x2c0, BIT(21) },
1169     [RST_AHB1_SPI2]     = { 0x2c0, BIT(22) },
1170     [RST_AHB1_SPI3]     = { 0x2c0, BIT(23) },
1171     [RST_AHB1_OTG]      = { 0x2c0, BIT(24) },
1172     [RST_AHB1_EHCI0]    = { 0x2c0, BIT(26) },
1173     [RST_AHB1_EHCI1]    = { 0x2c0, BIT(27) },
1174     [RST_AHB1_OHCI0]    = { 0x2c0, BIT(29) },
1175     [RST_AHB1_OHCI1]    = { 0x2c0, BIT(30) },
1176     [RST_AHB1_OHCI2]    = { 0x2c0, BIT(31) },
1177 
1178     [RST_AHB1_VE]       = { 0x2c4, BIT(0) },
1179     [RST_AHB1_LCD0]     = { 0x2c4, BIT(4) },
1180     [RST_AHB1_LCD1]     = { 0x2c4, BIT(5) },
1181     [RST_AHB1_CSI]      = { 0x2c4, BIT(8) },
1182     [RST_AHB1_HDMI]     = { 0x2c4, BIT(11) },
1183     [RST_AHB1_BE0]      = { 0x2c4, BIT(12) },
1184     [RST_AHB1_BE1]      = { 0x2c4, BIT(13) },
1185     [RST_AHB1_FE0]      = { 0x2c4, BIT(14) },
1186     [RST_AHB1_FE1]      = { 0x2c4, BIT(15) },
1187     [RST_AHB1_MP]       = { 0x2c4, BIT(18) },
1188     [RST_AHB1_GPU]      = { 0x2c4, BIT(20) },
1189     [RST_AHB1_DEU0]     = { 0x2c4, BIT(23) },
1190     [RST_AHB1_DEU1]     = { 0x2c4, BIT(24) },
1191     [RST_AHB1_DRC0]     = { 0x2c4, BIT(25) },
1192     [RST_AHB1_DRC1]     = { 0x2c4, BIT(26) },
1193     [RST_AHB1_LVDS]     = { 0x2c8, BIT(0) },
1194 
1195     [RST_APB1_CODEC]    = { 0x2d0, BIT(0) },
1196     [RST_APB1_SPDIF]    = { 0x2d0, BIT(1) },
1197     [RST_APB1_DIGITAL_MIC]  = { 0x2d0, BIT(4) },
1198     [RST_APB1_DAUDIO0]  = { 0x2d0, BIT(12) },
1199     [RST_APB1_DAUDIO1]  = { 0x2d0, BIT(13) },
1200 
1201     [RST_APB2_I2C0]     = { 0x2d8, BIT(0) },
1202     [RST_APB2_I2C1]     = { 0x2d8, BIT(1) },
1203     [RST_APB2_I2C2]     = { 0x2d8, BIT(2) },
1204     [RST_APB2_I2C3]     = { 0x2d8, BIT(3) },
1205     [RST_APB2_UART0]    = { 0x2d8, BIT(16) },
1206     [RST_APB2_UART1]    = { 0x2d8, BIT(17) },
1207     [RST_APB2_UART2]    = { 0x2d8, BIT(18) },
1208     [RST_APB2_UART3]    = { 0x2d8, BIT(19) },
1209     [RST_APB2_UART4]    = { 0x2d8, BIT(20) },
1210     [RST_APB2_UART5]    = { 0x2d8, BIT(21) },
1211 };
1212 
1213 static const struct sunxi_ccu_desc sun6i_a31_ccu_desc = {
1214     .ccu_clks   = sun6i_a31_ccu_clks,
1215     .num_ccu_clks   = ARRAY_SIZE(sun6i_a31_ccu_clks),
1216 
1217     .hw_clks    = &sun6i_a31_hw_clks,
1218 
1219     .resets     = sun6i_a31_ccu_resets,
1220     .num_resets = ARRAY_SIZE(sun6i_a31_ccu_resets),
1221 };
1222 
1223 static struct ccu_mux_nb sun6i_a31_cpu_nb = {
1224     .common     = &cpu_clk.common,
1225     .cm     = &cpu_clk.mux,
1226     .delay_us   = 1, /* > 8 clock cycles at 24 MHz */
1227     .bypass_index   = 1, /* index of 24 MHz oscillator */
1228 };
1229 
1230 static int sun6i_a31_ccu_probe(struct platform_device *pdev)
1231 {
1232     void __iomem *reg;
1233     int ret;
1234     u32 val;
1235 
1236     reg = devm_platform_ioremap_resource(pdev, 0);
1237     if (IS_ERR(reg))
1238         return PTR_ERR(reg);
1239 
1240     /* Force the PLL-Audio-1x divider to 1 */
1241     val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
1242     val &= ~GENMASK(19, 16);
1243     writel(val | (0 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
1244 
1245     /* Force PLL-MIPI to MIPI mode */
1246     val = readl(reg + SUN6I_A31_PLL_MIPI_REG);
1247     val &= BIT(16);
1248     writel(val, reg + SUN6I_A31_PLL_MIPI_REG);
1249 
1250     /* Force AHB1 to PLL6 / 3 */
1251     val = readl(reg + SUN6I_A31_AHB1_REG);
1252     /* set PLL6 pre-div = 3 */
1253     val &= ~GENMASK(7, 6);
1254     val |= 0x2 << 6;
1255     /* select PLL6 / pre-div */
1256     val &= ~GENMASK(13, 12);
1257     val |= 0x3 << 12;
1258     writel(val, reg + SUN6I_A31_AHB1_REG);
1259 
1260     ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun6i_a31_ccu_desc);
1261     if (ret)
1262         return ret;
1263 
1264     ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
1265                   &sun6i_a31_cpu_nb);
1266 
1267     return 0;
1268 }
1269 
1270 static const struct of_device_id sun6i_a31_ccu_ids[] = {
1271     { .compatible = "allwinner,sun6i-a31-ccu" },
1272     { }
1273 };
1274 
1275 static struct platform_driver sun6i_a31_ccu_driver = {
1276     .probe  = sun6i_a31_ccu_probe,
1277     .driver = {
1278         .name           = "sun6i-a31-ccu",
1279         .suppress_bind_attrs    = true,
1280         .of_match_table     = sun6i_a31_ccu_ids,
1281     },
1282 };
1283 module_platform_driver(sun6i_a31_ccu_driver);
1284 
1285 MODULE_IMPORT_NS(SUNXI_CCU);
1286 MODULE_LICENSE("GPL");