Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2017 Priit Laes <plaes@plaes.org>.
0004  * Copyright (c) 2017 Maxime Ripard.
0005  * Copyright (c) 2017 Jonathan Liu.
0006  */
0007 
0008 #include <linux/clk-provider.h>
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/of_device.h>
0012 #include <linux/platform_device.h>
0013 
0014 #include "ccu_common.h"
0015 #include "ccu_reset.h"
0016 
0017 #include "ccu_div.h"
0018 #include "ccu_gate.h"
0019 #include "ccu_mp.h"
0020 #include "ccu_mult.h"
0021 #include "ccu_nk.h"
0022 #include "ccu_nkm.h"
0023 #include "ccu_nkmp.h"
0024 #include "ccu_nm.h"
0025 #include "ccu_phase.h"
0026 #include "ccu_sdm.h"
0027 
0028 #include "ccu-sun4i-a10.h"
0029 
0030 static struct ccu_nkmp pll_core_clk = {
0031     .enable     = BIT(31),
0032     .n      = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
0033     .k      = _SUNXI_CCU_MULT(4, 2),
0034     .m      = _SUNXI_CCU_DIV(0, 2),
0035     .p      = _SUNXI_CCU_DIV(16, 2),
0036     .common     = {
0037         .reg        = 0x000,
0038         .hw.init    = CLK_HW_INIT("pll-core",
0039                           "hosc",
0040                           &ccu_nkmp_ops,
0041                           0),
0042     },
0043 };
0044 
0045 /*
0046  * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
0047  * the base (2x, 4x and 8x), and one variable divider (the one true
0048  * pll audio).
0049  *
0050  * With sigma-delta modulation for fractional-N on the audio PLL,
0051  * we have to use specific dividers. This means the variable divider
0052  * can no longer be used, as the audio codec requests the exact clock
0053  * rates we support through this mechanism. So we now hard code the
0054  * variable divider to 1. This means the clock rates will no longer
0055  * match the clock names.
0056  */
0057 #define SUN4I_PLL_AUDIO_REG 0x008
0058 
0059 static struct ccu_sdm_setting pll_audio_sdm_table[] = {
0060     { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
0061     { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
0062 };
0063 
0064 static struct ccu_nm pll_audio_base_clk = {
0065     .enable     = BIT(31),
0066     .n      = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
0067     .m      = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
0068     .sdm        = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
0069                      0x00c, BIT(31)),
0070     .common     = {
0071         .reg        = 0x008,
0072         .features   = CCU_FEATURE_SIGMA_DELTA_MOD,
0073         .hw.init    = CLK_HW_INIT("pll-audio-base",
0074                           "hosc",
0075                           &ccu_nm_ops,
0076                           0),
0077     },
0078 
0079 };
0080 
0081 static struct ccu_mult pll_video0_clk = {
0082     .enable     = BIT(31),
0083     .mult       = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
0084     .frac       = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
0085                       270000000, 297000000),
0086     .common     = {
0087         .reg        = 0x010,
0088         .features   = (CCU_FEATURE_FRACTIONAL |
0089                    CCU_FEATURE_ALL_PREDIV),
0090         .prediv     = 8,
0091         .hw.init    = CLK_HW_INIT("pll-video0",
0092                           "hosc",
0093                           &ccu_mult_ops,
0094                           0),
0095     },
0096 };
0097 
0098 static struct ccu_nkmp pll_ve_sun4i_clk = {
0099     .enable     = BIT(31),
0100     .n      = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
0101     .k      = _SUNXI_CCU_MULT(4, 2),
0102     .m      = _SUNXI_CCU_DIV(0, 2),
0103     .p      = _SUNXI_CCU_DIV(16, 2),
0104     .common     = {
0105         .reg        = 0x018,
0106         .hw.init    = CLK_HW_INIT("pll-ve",
0107                           "hosc",
0108                           &ccu_nkmp_ops,
0109                           0),
0110     },
0111 };
0112 
0113 static struct ccu_nk pll_ve_sun7i_clk = {
0114     .enable     = BIT(31),
0115     .n      = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
0116     .k      = _SUNXI_CCU_MULT(4, 2),
0117     .common     = {
0118         .reg        = 0x018,
0119         .hw.init    = CLK_HW_INIT("pll-ve",
0120                           "hosc",
0121                           &ccu_nk_ops,
0122                           0),
0123     },
0124 };
0125 
0126 static struct ccu_nk pll_ddr_base_clk = {
0127     .enable     = BIT(31),
0128     .n      = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
0129     .k      = _SUNXI_CCU_MULT(4, 2),
0130     .common     = {
0131         .reg        = 0x020,
0132         .hw.init    = CLK_HW_INIT("pll-ddr-base",
0133                           "hosc",
0134                           &ccu_nk_ops,
0135                           0),
0136     },
0137 };
0138 
0139 static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2,
0140            CLK_IS_CRITICAL);
0141 
0142 static struct ccu_div pll_ddr_other_clk = {
0143     .div        = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
0144     .common     = {
0145         .reg        = 0x020,
0146         .hw.init    = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
0147                           &ccu_div_ops,
0148                           0),
0149     },
0150 };
0151 
0152 static struct ccu_nk pll_periph_base_clk = {
0153     .enable     = BIT(31),
0154     .n      = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
0155     .k      = _SUNXI_CCU_MULT(4, 2),
0156     .common     = {
0157         .reg        = 0x028,
0158         .hw.init    = CLK_HW_INIT("pll-periph-base",
0159                           "hosc",
0160                           &ccu_nk_ops,
0161                           0),
0162     },
0163 };
0164 
0165 static CLK_FIXED_FACTOR_HW(pll_periph_clk, "pll-periph",
0166                &pll_periph_base_clk.common.hw,
0167                2, 1, CLK_SET_RATE_PARENT);
0168 
0169 /* Not documented on A10 */
0170 static struct ccu_div pll_periph_sata_clk = {
0171     .enable     = BIT(14),
0172     .div        = _SUNXI_CCU_DIV(0, 2),
0173     .fixed_post_div = 6,
0174     .common     = {
0175         .reg        = 0x028,
0176         .features   = CCU_FEATURE_FIXED_POSTDIV,
0177         .hw.init    = CLK_HW_INIT("pll-periph-sata",
0178                           "pll-periph-base",
0179                           &ccu_div_ops, 0),
0180     },
0181 };
0182 
0183 static struct ccu_mult pll_video1_clk = {
0184     .enable     = BIT(31),
0185     .mult       = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
0186     .frac       = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
0187                   270000000, 297000000),
0188     .common     = {
0189         .reg        = 0x030,
0190         .features   = (CCU_FEATURE_FRACTIONAL |
0191                    CCU_FEATURE_ALL_PREDIV),
0192         .prediv     = 8,
0193         .hw.init    = CLK_HW_INIT("pll-video1",
0194                           "hosc",
0195                           &ccu_mult_ops,
0196                           0),
0197     },
0198 };
0199 
0200 /* Not present on A10 */
0201 static struct ccu_nk pll_gpu_clk = {
0202     .enable     = BIT(31),
0203     .n      = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
0204     .k      = _SUNXI_CCU_MULT(4, 2),
0205     .common     = {
0206         .reg        = 0x040,
0207         .hw.init    = CLK_HW_INIT("pll-gpu",
0208                           "hosc",
0209                           &ccu_nk_ops,
0210                           0),
0211     },
0212 };
0213 
0214 static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0);
0215 
0216 static const char *const cpu_parents[] = { "osc32k", "hosc",
0217                        "pll-core", "pll-periph" };
0218 static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
0219     { .index = 3, .div = 3, },
0220 };
0221 
0222 #define SUN4I_AHB_REG       0x054
0223 static struct ccu_mux cpu_clk = {
0224     .mux        = {
0225         .shift      = 16,
0226         .width      = 2,
0227         .fixed_predivs  = cpu_predivs,
0228         .n_predivs  = ARRAY_SIZE(cpu_predivs),
0229     },
0230     .common     = {
0231         .reg        = 0x054,
0232         .features   = CCU_FEATURE_FIXED_PREDIV,
0233         .hw.init    = CLK_HW_INIT_PARENTS("cpu",
0234                               cpu_parents,
0235                               &ccu_mux_ops,
0236                               CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
0237     }
0238 };
0239 
0240 static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
0241 
0242 static struct ccu_div ahb_sun4i_clk = {
0243     .div        = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
0244     .common     = {
0245         .reg        = 0x054,
0246         .hw.init    = CLK_HW_INIT("ahb", "axi", &ccu_div_ops, 0),
0247     },
0248 };
0249 
0250 static const char *const ahb_sun7i_parents[] = { "axi", "pll-periph",
0251                          "pll-periph" };
0252 static const struct ccu_mux_fixed_prediv ahb_sun7i_predivs[] = {
0253     { .index = 1, .div = 2, },
0254     { /* Sentinel */ },
0255 };
0256 static struct ccu_div ahb_sun7i_clk = {
0257     .div        = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
0258     .mux        = {
0259         .shift      = 6,
0260         .width      = 2,
0261         .fixed_predivs  = ahb_sun7i_predivs,
0262         .n_predivs  = ARRAY_SIZE(ahb_sun7i_predivs),
0263     },
0264 
0265     .common     = {
0266         .reg        = 0x054,
0267         .hw.init    = CLK_HW_INIT_PARENTS("ahb",
0268                               ahb_sun7i_parents,
0269                               &ccu_div_ops,
0270                               0),
0271     },
0272 };
0273 
0274 static struct clk_div_table apb0_div_table[] = {
0275     { .val = 0, .div = 2 },
0276     { .val = 1, .div = 2 },
0277     { .val = 2, .div = 4 },
0278     { .val = 3, .div = 8 },
0279     { /* Sentinel */ },
0280 };
0281 static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
0282                0x054, 8, 2, apb0_div_table, 0);
0283 
0284 static const char *const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
0285 static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
0286                  0, 5,  /* M */
0287                  16, 2, /* P */
0288                  24, 2, /* mux */
0289                  0);
0290 
0291 /* Not present on A20 */
0292 static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "ahb",
0293               0x05c, BIT(31), 0);
0294 
0295 static SUNXI_CCU_GATE(ahb_otg_clk,  "ahb-otg",  "ahb",
0296               0x060, BIT(0), 0);
0297 static SUNXI_CCU_GATE(ahb_ehci0_clk,    "ahb-ehci0",    "ahb",
0298               0x060, BIT(1), 0);
0299 static SUNXI_CCU_GATE(ahb_ohci0_clk,    "ahb-ohci0",    "ahb",
0300               0x060, BIT(2), 0);
0301 static SUNXI_CCU_GATE(ahb_ehci1_clk,    "ahb-ehci1",    "ahb",
0302               0x060, BIT(3), 0);
0303 static SUNXI_CCU_GATE(ahb_ohci1_clk,    "ahb-ohci1",    "ahb",
0304               0x060, BIT(4), 0);
0305 static SUNXI_CCU_GATE(ahb_ss_clk,   "ahb-ss",   "ahb",
0306               0x060, BIT(5), 0);
0307 static SUNXI_CCU_GATE(ahb_dma_clk,  "ahb-dma",  "ahb",
0308               0x060, BIT(6), 0);
0309 static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb",
0310               0x060, BIT(7), 0);
0311 static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb",
0312               0x060, BIT(8), 0);
0313 static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb",
0314               0x060, BIT(9), 0);
0315 static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb",
0316               0x060, BIT(10), 0);
0317 static SUNXI_CCU_GATE(ahb_mmc3_clk, "ahb-mmc3", "ahb",
0318               0x060, BIT(11), 0);
0319 static SUNXI_CCU_GATE(ahb_ms_clk,   "ahb-ms",   "ahb",
0320               0x060, BIT(12), 0);
0321 static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb",
0322               0x060, BIT(13), 0);
0323 static SUNXI_CCU_GATE(ahb_sdram_clk,    "ahb-sdram",    "ahb",
0324               0x060, BIT(14), CLK_IS_CRITICAL);
0325 
0326 static SUNXI_CCU_GATE(ahb_ace_clk,  "ahb-ace",  "ahb",
0327               0x060, BIT(16), 0);
0328 static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb",
0329               0x060, BIT(17), 0);
0330 static SUNXI_CCU_GATE(ahb_ts_clk,   "ahb-ts",   "ahb",
0331               0x060, BIT(18), 0);
0332 static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb",
0333               0x060, BIT(20), 0);
0334 static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb",
0335               0x060, BIT(21), 0);
0336 static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb",
0337               0x060, BIT(22), 0);
0338 static SUNXI_CCU_GATE(ahb_spi3_clk, "ahb-spi3", "ahb",
0339               0x060, BIT(23), 0);
0340 static SUNXI_CCU_GATE(ahb_pata_clk, "ahb-pata", "ahb",
0341               0x060, BIT(24), 0);
0342 /* Not documented on A20 */
0343 static SUNXI_CCU_GATE(ahb_sata_clk, "ahb-sata", "ahb",
0344               0x060, BIT(25), 0);
0345 /* Not present on A20 */
0346 static SUNXI_CCU_GATE(ahb_gps_clk,  "ahb-gps",  "ahb",
0347               0x060, BIT(26), 0);
0348 /* Not present on A10 */
0349 static SUNXI_CCU_GATE(ahb_hstimer_clk,  "ahb-hstimer",  "ahb",
0350               0x060, BIT(28), 0);
0351 
0352 static SUNXI_CCU_GATE(ahb_ve_clk,   "ahb-ve",   "ahb",
0353               0x064, BIT(0), 0);
0354 static SUNXI_CCU_GATE(ahb_tvd_clk,  "ahb-tvd",  "ahb",
0355               0x064, BIT(1), 0);
0356 static SUNXI_CCU_GATE(ahb_tve0_clk, "ahb-tve0", "ahb",
0357               0x064, BIT(2), 0);
0358 static SUNXI_CCU_GATE(ahb_tve1_clk, "ahb-tve1", "ahb",
0359               0x064, BIT(3), 0);
0360 static SUNXI_CCU_GATE(ahb_lcd0_clk, "ahb-lcd0", "ahb",
0361               0x064, BIT(4), 0);
0362 static SUNXI_CCU_GATE(ahb_lcd1_clk, "ahb-lcd1", "ahb",
0363               0x064, BIT(5), 0);
0364 static SUNXI_CCU_GATE(ahb_csi0_clk, "ahb-csi0", "ahb",
0365               0x064, BIT(8), 0);
0366 static SUNXI_CCU_GATE(ahb_csi1_clk, "ahb-csi1", "ahb",
0367               0x064, BIT(9), 0);
0368 /* Not present on A10 */
0369 static SUNXI_CCU_GATE(ahb_hdmi1_clk,    "ahb-hdmi1",    "ahb",
0370               0x064, BIT(10), 0);
0371 static SUNXI_CCU_GATE(ahb_hdmi0_clk,    "ahb-hdmi0",    "ahb",
0372               0x064, BIT(11), 0);
0373 static SUNXI_CCU_GATE(ahb_de_be0_clk,   "ahb-de-be0",   "ahb",
0374               0x064, BIT(12), 0);
0375 static SUNXI_CCU_GATE(ahb_de_be1_clk,   "ahb-de-be1",   "ahb",
0376               0x064, BIT(13), 0);
0377 static SUNXI_CCU_GATE(ahb_de_fe0_clk,   "ahb-de-fe0",   "ahb",
0378               0x064, BIT(14), 0);
0379 static SUNXI_CCU_GATE(ahb_de_fe1_clk,   "ahb-de-fe1",   "ahb",
0380               0x064, BIT(15), 0);
0381 /* Not present on A10 */
0382 static SUNXI_CCU_GATE(ahb_gmac_clk, "ahb-gmac", "ahb",
0383               0x064, BIT(17), 0);
0384 static SUNXI_CCU_GATE(ahb_mp_clk,   "ahb-mp",   "ahb",
0385               0x064, BIT(18), 0);
0386 static SUNXI_CCU_GATE(ahb_gpu_clk,  "ahb-gpu",  "ahb",
0387               0x064, BIT(20), 0);
0388 
0389 static SUNXI_CCU_GATE(apb0_codec_clk,   "apb0-codec",   "apb0",
0390               0x068, BIT(0), 0);
0391 static SUNXI_CCU_GATE(apb0_spdif_clk,   "apb0-spdif",   "apb0",
0392               0x068, BIT(1), 0);
0393 static SUNXI_CCU_GATE(apb0_ac97_clk,    "apb0-ac97",    "apb0",
0394               0x068, BIT(2), 0);
0395 static SUNXI_CCU_GATE(apb0_i2s0_clk,    "apb0-i2s0",    "apb0",
0396               0x068, BIT(3), 0);
0397 /* Not present on A10 */
0398 static SUNXI_CCU_GATE(apb0_i2s1_clk,    "apb0-i2s1",    "apb0",
0399               0x068, BIT(4), 0);
0400 static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
0401               0x068, BIT(5), 0);
0402 static SUNXI_CCU_GATE(apb0_ir0_clk, "apb0-ir0", "apb0",
0403               0x068, BIT(6), 0);
0404 static SUNXI_CCU_GATE(apb0_ir1_clk, "apb0-ir1", "apb0",
0405               0x068, BIT(7), 0);
0406 /* Not present on A10 */
0407 static SUNXI_CCU_GATE(apb0_i2s2_clk,    "apb0-i2s2",    "apb0",
0408               0x068, BIT(8), 0);
0409 static SUNXI_CCU_GATE(apb0_keypad_clk,  "apb0-keypad",  "apb0",
0410               0x068, BIT(10), 0);
0411 
0412 static SUNXI_CCU_GATE(apb1_i2c0_clk,    "apb1-i2c0",    "apb1",
0413               0x06c, BIT(0), 0);
0414 static SUNXI_CCU_GATE(apb1_i2c1_clk,    "apb1-i2c1",    "apb1",
0415               0x06c, BIT(1), 0);
0416 static SUNXI_CCU_GATE(apb1_i2c2_clk,    "apb1-i2c2",    "apb1",
0417               0x06c, BIT(2), 0);
0418 /* Not present on A10 */
0419 static SUNXI_CCU_GATE(apb1_i2c3_clk,    "apb1-i2c3",    "apb1",
0420               0x06c, BIT(3), 0);
0421 static SUNXI_CCU_GATE(apb1_can_clk, "apb1-can", "apb1",
0422               0x06c, BIT(4), 0);
0423 static SUNXI_CCU_GATE(apb1_scr_clk, "apb1-scr", "apb1",
0424               0x06c, BIT(5), 0);
0425 static SUNXI_CCU_GATE(apb1_ps20_clk,    "apb1-ps20",    "apb1",
0426               0x06c, BIT(6), 0);
0427 static SUNXI_CCU_GATE(apb1_ps21_clk,    "apb1-ps21",    "apb1",
0428               0x06c, BIT(7), 0);
0429 /* Not present on A10 */
0430 static SUNXI_CCU_GATE(apb1_i2c4_clk,    "apb1-i2c4",    "apb1",
0431               0x06c, BIT(15), 0);
0432 static SUNXI_CCU_GATE(apb1_uart0_clk,   "apb1-uart0",   "apb1",
0433               0x06c, BIT(16), 0);
0434 static SUNXI_CCU_GATE(apb1_uart1_clk,   "apb1-uart1",   "apb1",
0435               0x06c, BIT(17), 0);
0436 static SUNXI_CCU_GATE(apb1_uart2_clk,   "apb1-uart2",   "apb1",
0437               0x06c, BIT(18), 0);
0438 static SUNXI_CCU_GATE(apb1_uart3_clk,   "apb1-uart3",   "apb1",
0439               0x06c, BIT(19), 0);
0440 static SUNXI_CCU_GATE(apb1_uart4_clk,   "apb1-uart4",   "apb1",
0441               0x06c, BIT(20), 0);
0442 static SUNXI_CCU_GATE(apb1_uart5_clk,   "apb1-uart5",   "apb1",
0443               0x06c, BIT(21), 0);
0444 static SUNXI_CCU_GATE(apb1_uart6_clk,   "apb1-uart6",   "apb1",
0445               0x06c, BIT(22), 0);
0446 static SUNXI_CCU_GATE(apb1_uart7_clk,   "apb1-uart7",   "apb1",
0447               0x06c, BIT(23), 0);
0448 
0449 static const char *const mod0_default_parents[] = { "hosc", "pll-periph",
0450                              "pll-ddr-other" };
0451 static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
0452                   0, 4,     /* M */
0453                   16, 2,    /* P */
0454                   24, 2,    /* mux */
0455                   BIT(31),  /* gate */
0456                   0);
0457 
0458 /* Undocumented on A10 */
0459 static SUNXI_CCU_MP_WITH_MUX_GATE(ms_clk, "ms", mod0_default_parents, 0x084,
0460                   0, 4,     /* M */
0461                   16, 2,    /* P */
0462                   24, 2,    /* mux */
0463                   BIT(31),  /* gate */
0464                   0);
0465 
0466 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
0467                   0, 4,     /* M */
0468                   16, 2,    /* P */
0469                   24, 2,    /* mux */
0470                   BIT(31),  /* gate */
0471                   0);
0472 
0473 /* MMC output and sample clocks are not present on A10 */
0474 static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
0475                0x088, 8, 3, 0);
0476 static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
0477                0x088, 20, 3, 0);
0478 
0479 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
0480                   0, 4,     /* M */
0481                   16, 2,    /* P */
0482                   24, 2,    /* mux */
0483                   BIT(31),  /* gate */
0484                   0);
0485 
0486 /* MMC output and sample clocks are not present on A10 */
0487 static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
0488                0x08c, 8, 3, 0);
0489 static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
0490                0x08c, 20, 3, 0);
0491 
0492 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
0493                   0, 4,     /* M */
0494                   16, 2,    /* P */
0495                   24, 2,    /* mux */
0496                   BIT(31),  /* gate */
0497                   0);
0498 
0499 /* MMC output and sample clocks are not present on A10 */
0500 static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
0501                0x090, 8, 3, 0);
0502 static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
0503                0x090, 20, 3, 0);
0504 
0505 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094,
0506                   0, 4,     /* M */
0507                   16, 2,    /* P */
0508                   24, 2,    /* mux */
0509                   BIT(31),  /* gate */
0510                   0);
0511 
0512 /* MMC output and sample clocks are not present on A10 */
0513 static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3",
0514                0x094, 8, 3, 0);
0515 static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3",
0516                0x094, 20, 3, 0);
0517 
0518 static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
0519                   0, 4,     /* M */
0520                   16, 2,    /* P */
0521                   24, 2,    /* mux */
0522                   BIT(31),  /* gate */
0523                   0);
0524 
0525 static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
0526                   0, 4,     /* M */
0527                   16, 2,    /* P */
0528                   24, 2,    /* mux */
0529                   BIT(31),  /* gate */
0530                   0);
0531 
0532 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
0533                   0, 4,     /* M */
0534                   16, 2,    /* P */
0535                   24, 2,    /* mux */
0536                   BIT(31),  /* gate */
0537                   0);
0538 
0539 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
0540                   0, 4,     /* M */
0541                   16, 2,    /* P */
0542                   24, 2,    /* mux */
0543                   BIT(31),  /* gate */
0544                   0);
0545 
0546 static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
0547                   0, 4,     /* M */
0548                   16, 2,    /* P */
0549                   24, 2,    /* mux */
0550                   BIT(31),  /* gate */
0551                   0);
0552 
0553 /* Undocumented on A10 */
0554 static SUNXI_CCU_MP_WITH_MUX_GATE(pata_clk, "pata", mod0_default_parents, 0x0ac,
0555                   0, 4,     /* M */
0556                   16, 2,    /* P */
0557                   24, 2,    /* mux */
0558                   BIT(31),  /* gate */
0559                   0);
0560 
0561 /* TODO: Check whether A10 actually supports osc32k as 4th parent? */
0562 static const char *const ir_parents_sun4i[] = { "hosc", "pll-periph",
0563                         "pll-ddr-other" };
0564 static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun4i_clk, "ir0", ir_parents_sun4i, 0x0b0,
0565                   0, 4,     /* M */
0566                   16, 2,    /* P */
0567                   24, 2,    /* mux */
0568                   BIT(31),  /* gate */
0569                   0);
0570 
0571 static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun4i_clk, "ir1", ir_parents_sun4i, 0x0b4,
0572                   0, 4,     /* M */
0573                   16, 2,    /* P */
0574                   24, 2,    /* mux */
0575                   BIT(31),  /* gate */
0576                   0);
0577 static const char *const ir_parents_sun7i[] = { "hosc", "pll-periph",
0578                         "pll-ddr-other", "osc32k" };
0579 static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun7i_clk, "ir0", ir_parents_sun7i, 0x0b0,
0580                   0, 4,     /* M */
0581                   16, 2,    /* P */
0582                   24, 2,    /* mux */
0583                   BIT(31),  /* gate */
0584                   0);
0585 
0586 static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun7i_clk, "ir1", ir_parents_sun7i, 0x0b4,
0587                   0, 4,     /* M */
0588                   16, 2,    /* P */
0589                   24, 2,    /* mux */
0590                   BIT(31),  /* gate */
0591                   0);
0592 
0593 static const char *const audio_parents[] = { "pll-audio-8x", "pll-audio-4x",
0594                           "pll-audio-2x", "pll-audio" };
0595 static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", audio_parents,
0596                    0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0597 
0598 static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", audio_parents,
0599                    0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0600 
0601 /* Undocumented on A10 */
0602 static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", audio_parents,
0603                    0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0604 
0605 static const char *const keypad_parents[] = { "hosc", "losc"};
0606 static const u8 keypad_table[] = { 0, 2 };
0607 static struct ccu_mp keypad_clk = {
0608     .enable     = BIT(31),
0609     .m      = _SUNXI_CCU_DIV(0, 5),
0610     .p      = _SUNXI_CCU_DIV(16, 2),
0611     .mux        = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
0612     .common     = {
0613         .reg        = 0x0c4,
0614         .hw.init    = CLK_HW_INIT_PARENTS("keypad",
0615                               keypad_parents,
0616                               &ccu_mp_ops,
0617                               0),
0618     },
0619 };
0620 
0621 /*
0622  * SATA supports external clock as parent via BIT(24) and is probably an
0623  * optional crystal or oscillator that can be connected to the
0624  * SATA-CLKM / SATA-CLKP pins.
0625  */
0626 static const char *const sata_parents[] = {"pll-periph-sata", "sata-ext"};
0627 static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents,
0628                    0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT);
0629 
0630 
0631 static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "pll-periph",
0632               0x0cc, BIT(6), 0);
0633 static SUNXI_CCU_GATE(usb_ohci1_clk,    "usb-ohci1",    "pll-periph",
0634               0x0cc, BIT(7), 0);
0635 static SUNXI_CCU_GATE(usb_phy_clk,  "usb-phy",  "pll-periph",
0636               0x0cc, BIT(8), 0);
0637 
0638 /* TODO: GPS CLK 0x0d0 */
0639 
0640 static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0d4,
0641                   0, 4,     /* M */
0642                   16, 2,    /* P */
0643                   24, 2,    /* mux */
0644                   BIT(31),  /* gate */
0645                   0);
0646 
0647 /* Not present on A10 */
0648 static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", audio_parents,
0649                    0x0d8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0650 
0651 /* Not present on A10 */
0652 static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", audio_parents,
0653                    0x0dc, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
0654 
0655 static SUNXI_CCU_GATE(dram_ve_clk,  "dram-ve",  "pll-ddr",
0656               0x100, BIT(0), 0);
0657 static SUNXI_CCU_GATE(dram_csi0_clk,    "dram-csi0",    "pll-ddr",
0658               0x100, BIT(1), 0);
0659 static SUNXI_CCU_GATE(dram_csi1_clk,    "dram-csi1",    "pll-ddr",
0660               0x100, BIT(2), 0);
0661 static SUNXI_CCU_GATE(dram_ts_clk,  "dram-ts",  "pll-ddr",
0662               0x100, BIT(3), 0);
0663 static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "pll-ddr",
0664               0x100, BIT(4), 0);
0665 static SUNXI_CCU_GATE(dram_tve0_clk,    "dram-tve0",    "pll-ddr",
0666               0x100, BIT(5), 0);
0667 static SUNXI_CCU_GATE(dram_tve1_clk,    "dram-tve1",    "pll-ddr",
0668               0x100, BIT(6), 0);
0669 
0670 /* Clock seems to be critical only on sun4i */
0671 static SUNXI_CCU_GATE(dram_out_clk, "dram-out", "pll-ddr",
0672               0x100, BIT(15), CLK_IS_CRITICAL);
0673 static SUNXI_CCU_GATE(dram_de_fe1_clk,  "dram-de-fe1",  "pll-ddr",
0674               0x100, BIT(24), 0);
0675 static SUNXI_CCU_GATE(dram_de_fe0_clk,  "dram-de-fe0",  "pll-ddr",
0676               0x100, BIT(25), 0);
0677 static SUNXI_CCU_GATE(dram_de_be0_clk,  "dram-de-be0",  "pll-ddr",
0678               0x100, BIT(26), 0);
0679 static SUNXI_CCU_GATE(dram_de_be1_clk,  "dram-de-be1",  "pll-ddr",
0680               0x100, BIT(27), 0);
0681 static SUNXI_CCU_GATE(dram_mp_clk,  "dram-mp",  "pll-ddr",
0682               0x100, BIT(28), 0);
0683 static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr",
0684               0x100, BIT(29), 0);
0685 
0686 static const char *const de_parents[] = { "pll-video0", "pll-video1",
0687                        "pll-ddr-other" };
0688 static SUNXI_CCU_M_WITH_MUX_GATE(de_be0_clk, "de-be0", de_parents,
0689                  0x104, 0, 4, 24, 2, BIT(31), 0);
0690 
0691 static SUNXI_CCU_M_WITH_MUX_GATE(de_be1_clk, "de-be1", de_parents,
0692                  0x108, 0, 4, 24, 2, BIT(31), 0);
0693 
0694 static SUNXI_CCU_M_WITH_MUX_GATE(de_fe0_clk, "de-fe0", de_parents,
0695                  0x10c, 0, 4, 24, 2, BIT(31), 0);
0696 
0697 static SUNXI_CCU_M_WITH_MUX_GATE(de_fe1_clk, "de-fe1", de_parents,
0698                  0x110, 0, 4, 24, 2, BIT(31), 0);
0699 
0700 /* Undocumented on A10 */
0701 static SUNXI_CCU_M_WITH_MUX_GATE(de_mp_clk, "de-mp", de_parents,
0702                  0x114, 0, 4, 24, 2, BIT(31), 0);
0703 
0704 static const char *const disp_parents[] = { "pll-video0", "pll-video1",
0705                         "pll-video0-2x", "pll-video1-2x" };
0706 static SUNXI_CCU_MUX_WITH_GATE(tcon0_ch0_clk, "tcon0-ch0-sclk", disp_parents,
0707                    0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
0708 static SUNXI_CCU_MUX_WITH_GATE(tcon1_ch0_clk, "tcon1-ch0-sclk", disp_parents,
0709                    0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
0710 
0711 static const char *const csi_sclk_parents[] = { "pll-video0", "pll-ve",
0712                         "pll-ddr-other", "pll-periph" };
0713 
0714 static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk",
0715                  csi_sclk_parents,
0716                  0x120, 0, 4, 24, 2, BIT(31), 0);
0717 
0718 /* TVD clock setup for A10 */
0719 static const char *const tvd_parents[] = { "pll-video0", "pll-video1" };
0720 static SUNXI_CCU_MUX_WITH_GATE(tvd_sun4i_clk, "tvd", tvd_parents,
0721                    0x128, 24, 1, BIT(31), 0);
0722 
0723 /* TVD clock setup for A20 */
0724 static SUNXI_CCU_MP_WITH_MUX_GATE(tvd_sclk2_sun7i_clk,
0725                   "tvd-sclk2", tvd_parents,
0726                   0x128,
0727                   0, 4,     /* M */
0728                   16, 4,    /* P */
0729                   8, 1,     /* mux */
0730                   BIT(15),  /* gate */
0731                   0);
0732 
0733 static SUNXI_CCU_M_WITH_GATE(tvd_sclk1_sun7i_clk, "tvd-sclk1", "tvd-sclk2",
0734                  0x128, 0, 4, BIT(31), 0);
0735 
0736 static SUNXI_CCU_M_WITH_MUX_GATE(tcon0_ch1_sclk2_clk, "tcon0-ch1-sclk2",
0737                  disp_parents,
0738                  0x12c, 0, 4, 24, 2, BIT(31),
0739                  CLK_SET_RATE_PARENT);
0740 
0741 static SUNXI_CCU_M_WITH_GATE(tcon0_ch1_clk,
0742                  "tcon0-ch1-sclk1", "tcon0-ch1-sclk2",
0743                  0x12c, 11, 1, BIT(15),
0744                  CLK_SET_RATE_PARENT);
0745 
0746 static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_ch1_sclk2_clk, "tcon1-ch1-sclk2",
0747                  disp_parents,
0748                  0x130, 0, 4, 24, 2, BIT(31),
0749                  CLK_SET_RATE_PARENT);
0750 
0751 static SUNXI_CCU_M_WITH_GATE(tcon1_ch1_clk,
0752                  "tcon1-ch1-sclk1", "tcon1-ch1-sclk2",
0753                  0x130, 11, 1, BIT(15),
0754                  CLK_SET_RATE_PARENT);
0755 
0756 static const char *const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
0757                        "pll-video0-2x", "pll-video1-2x"};
0758 static const u8 csi_table[] = { 0, 1, 2, 5, 6};
0759 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_clk, "csi0",
0760                        csi_parents, csi_table,
0761                        0x134, 0, 5, 24, 3, BIT(31), 0);
0762 
0763 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_clk, "csi1",
0764                        csi_parents, csi_table,
0765                        0x138, 0, 5, 24, 3, BIT(31), 0);
0766 
0767 static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, 16, 8, BIT(31), 0);
0768 
0769 static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
0770               0x140, BIT(31), CLK_SET_RATE_PARENT);
0771 
0772 static SUNXI_CCU_GATE(avs_clk, "avs", "hosc", 0x144, BIT(31), 0);
0773 
0774 static const char *const ace_parents[] = { "pll-ve", "pll-ddr-other" };
0775 static SUNXI_CCU_M_WITH_MUX_GATE(ace_clk, "ace", ace_parents,
0776                  0x148, 0, 4, 24, 1, BIT(31), 0);
0777 
0778 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", disp_parents,
0779                  0x150, 0, 4, 24, 2, BIT(31),
0780                  CLK_SET_RATE_PARENT);
0781 
0782 static const char *const gpu_parents_sun4i[] = { "pll-video0", "pll-ve",
0783                          "pll-ddr-other",
0784                          "pll-video1" };
0785 static SUNXI_CCU_M_WITH_MUX_GATE(gpu_sun4i_clk, "gpu", gpu_parents_sun4i,
0786                  0x154, 0, 4, 24, 2, BIT(31),
0787                  CLK_SET_RATE_PARENT);
0788 
0789 static const char *const gpu_parents_sun7i[] = { "pll-video0", "pll-ve",
0790                          "pll-ddr-other", "pll-video1",
0791                          "pll-gpu" };
0792 static const u8 gpu_table_sun7i[] = { 0, 1, 2, 3, 4 };
0793 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_sun7i_clk, "gpu",
0794                        gpu_parents_sun7i, gpu_table_sun7i,
0795                        0x154, 0, 4, 24, 3, BIT(31),
0796                        CLK_SET_RATE_PARENT);
0797 
0798 static const char *const mbus_sun4i_parents[] = { "hosc", "pll-periph",
0799                           "pll-ddr-other" };
0800 static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun4i_clk, "mbus", mbus_sun4i_parents,
0801                   0x15c, 0, 4, 16, 2, 24, 2, BIT(31),
0802                   0);
0803 static const char *const mbus_sun7i_parents[] = { "hosc", "pll-periph-base",
0804                           "pll-ddr-other" };
0805 static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun7i_clk, "mbus", mbus_sun7i_parents,
0806                   0x15c, 0, 4, 16, 2, 24, 2, BIT(31),
0807                   CLK_IS_CRITICAL);
0808 
0809 static SUNXI_CCU_GATE(hdmi1_slow_clk, "hdmi1-slow", "hosc", 0x178, BIT(31), 0);
0810 
0811 static const char *const hdmi1_parents[] = { "pll-video0", "pll-video1" };
0812 static const u8 hdmi1_table[] = { 0, 1};
0813 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi1_clk, "hdmi1",
0814                        hdmi1_parents, hdmi1_table,
0815                        0x17c, 0, 4, 24, 2, BIT(31),
0816                        CLK_SET_RATE_PARENT);
0817 
0818 static const char *const out_parents[] = { "hosc", "osc32k", "hosc" };
0819 static const struct ccu_mux_fixed_prediv clk_out_predivs[] = {
0820     { .index = 0, .div = 750, },
0821 };
0822 
0823 static struct ccu_mp out_a_clk = {
0824     .enable     = BIT(31),
0825     .m      = _SUNXI_CCU_DIV(8, 5),
0826     .p      = _SUNXI_CCU_DIV(20, 2),
0827     .mux        = {
0828         .shift      = 24,
0829         .width      = 2,
0830         .fixed_predivs  = clk_out_predivs,
0831         .n_predivs  = ARRAY_SIZE(clk_out_predivs),
0832     },
0833     .common     = {
0834         .reg        = 0x1f0,
0835         .features   = CCU_FEATURE_FIXED_PREDIV,
0836         .hw.init    = CLK_HW_INIT_PARENTS("out-a",
0837                               out_parents,
0838                               &ccu_mp_ops,
0839                               0),
0840     },
0841 };
0842 static struct ccu_mp out_b_clk = {
0843     .enable     = BIT(31),
0844     .m      = _SUNXI_CCU_DIV(8, 5),
0845     .p      = _SUNXI_CCU_DIV(20, 2),
0846     .mux        = {
0847         .shift      = 24,
0848         .width      = 2,
0849         .fixed_predivs  = clk_out_predivs,
0850         .n_predivs  = ARRAY_SIZE(clk_out_predivs),
0851     },
0852     .common     = {
0853         .reg        = 0x1f4,
0854         .features   = CCU_FEATURE_FIXED_PREDIV,
0855         .hw.init    = CLK_HW_INIT_PARENTS("out-b",
0856                               out_parents,
0857                               &ccu_mp_ops,
0858                               0),
0859     },
0860 };
0861 
0862 static struct ccu_common *sun4i_sun7i_ccu_clks[] = {
0863     &hosc_clk.common,
0864     &pll_core_clk.common,
0865     &pll_audio_base_clk.common,
0866     &pll_video0_clk.common,
0867     &pll_ve_sun4i_clk.common,
0868     &pll_ve_sun7i_clk.common,
0869     &pll_ddr_base_clk.common,
0870     &pll_ddr_clk.common,
0871     &pll_ddr_other_clk.common,
0872     &pll_periph_base_clk.common,
0873     &pll_periph_sata_clk.common,
0874     &pll_video1_clk.common,
0875     &pll_gpu_clk.common,
0876     &cpu_clk.common,
0877     &axi_clk.common,
0878     &axi_dram_clk.common,
0879     &ahb_sun4i_clk.common,
0880     &ahb_sun7i_clk.common,
0881     &apb0_clk.common,
0882     &apb1_clk.common,
0883     &ahb_otg_clk.common,
0884     &ahb_ehci0_clk.common,
0885     &ahb_ohci0_clk.common,
0886     &ahb_ehci1_clk.common,
0887     &ahb_ohci1_clk.common,
0888     &ahb_ss_clk.common,
0889     &ahb_dma_clk.common,
0890     &ahb_bist_clk.common,
0891     &ahb_mmc0_clk.common,
0892     &ahb_mmc1_clk.common,
0893     &ahb_mmc2_clk.common,
0894     &ahb_mmc3_clk.common,
0895     &ahb_ms_clk.common,
0896     &ahb_nand_clk.common,
0897     &ahb_sdram_clk.common,
0898     &ahb_ace_clk.common,
0899     &ahb_emac_clk.common,
0900     &ahb_ts_clk.common,
0901     &ahb_spi0_clk.common,
0902     &ahb_spi1_clk.common,
0903     &ahb_spi2_clk.common,
0904     &ahb_spi3_clk.common,
0905     &ahb_pata_clk.common,
0906     &ahb_sata_clk.common,
0907     &ahb_gps_clk.common,
0908     &ahb_hstimer_clk.common,
0909     &ahb_ve_clk.common,
0910     &ahb_tvd_clk.common,
0911     &ahb_tve0_clk.common,
0912     &ahb_tve1_clk.common,
0913     &ahb_lcd0_clk.common,
0914     &ahb_lcd1_clk.common,
0915     &ahb_csi0_clk.common,
0916     &ahb_csi1_clk.common,
0917     &ahb_hdmi1_clk.common,
0918     &ahb_hdmi0_clk.common,
0919     &ahb_de_be0_clk.common,
0920     &ahb_de_be1_clk.common,
0921     &ahb_de_fe0_clk.common,
0922     &ahb_de_fe1_clk.common,
0923     &ahb_gmac_clk.common,
0924     &ahb_mp_clk.common,
0925     &ahb_gpu_clk.common,
0926     &apb0_codec_clk.common,
0927     &apb0_spdif_clk.common,
0928     &apb0_ac97_clk.common,
0929     &apb0_i2s0_clk.common,
0930     &apb0_i2s1_clk.common,
0931     &apb0_pio_clk.common,
0932     &apb0_ir0_clk.common,
0933     &apb0_ir1_clk.common,
0934     &apb0_i2s2_clk.common,
0935     &apb0_keypad_clk.common,
0936     &apb1_i2c0_clk.common,
0937     &apb1_i2c1_clk.common,
0938     &apb1_i2c2_clk.common,
0939     &apb1_i2c3_clk.common,
0940     &apb1_can_clk.common,
0941     &apb1_scr_clk.common,
0942     &apb1_ps20_clk.common,
0943     &apb1_ps21_clk.common,
0944     &apb1_i2c4_clk.common,
0945     &apb1_uart0_clk.common,
0946     &apb1_uart1_clk.common,
0947     &apb1_uart2_clk.common,
0948     &apb1_uart3_clk.common,
0949     &apb1_uart4_clk.common,
0950     &apb1_uart5_clk.common,
0951     &apb1_uart6_clk.common,
0952     &apb1_uart7_clk.common,
0953     &nand_clk.common,
0954     &ms_clk.common,
0955     &mmc0_clk.common,
0956     &mmc0_output_clk.common,
0957     &mmc0_sample_clk.common,
0958     &mmc1_clk.common,
0959     &mmc1_output_clk.common,
0960     &mmc1_sample_clk.common,
0961     &mmc2_clk.common,
0962     &mmc2_output_clk.common,
0963     &mmc2_sample_clk.common,
0964     &mmc3_clk.common,
0965     &mmc3_output_clk.common,
0966     &mmc3_sample_clk.common,
0967     &ts_clk.common,
0968     &ss_clk.common,
0969     &spi0_clk.common,
0970     &spi1_clk.common,
0971     &spi2_clk.common,
0972     &pata_clk.common,
0973     &ir0_sun4i_clk.common,
0974     &ir1_sun4i_clk.common,
0975     &ir0_sun7i_clk.common,
0976     &ir1_sun7i_clk.common,
0977     &i2s0_clk.common,
0978     &ac97_clk.common,
0979     &spdif_clk.common,
0980     &keypad_clk.common,
0981     &sata_clk.common,
0982     &usb_ohci0_clk.common,
0983     &usb_ohci1_clk.common,
0984     &usb_phy_clk.common,
0985     &spi3_clk.common,
0986     &i2s1_clk.common,
0987     &i2s2_clk.common,
0988     &dram_ve_clk.common,
0989     &dram_csi0_clk.common,
0990     &dram_csi1_clk.common,
0991     &dram_ts_clk.common,
0992     &dram_tvd_clk.common,
0993     &dram_tve0_clk.common,
0994     &dram_tve1_clk.common,
0995     &dram_out_clk.common,
0996     &dram_de_fe1_clk.common,
0997     &dram_de_fe0_clk.common,
0998     &dram_de_be0_clk.common,
0999     &dram_de_be1_clk.common,
1000     &dram_mp_clk.common,
1001     &dram_ace_clk.common,
1002     &de_be0_clk.common,
1003     &de_be1_clk.common,
1004     &de_fe0_clk.common,
1005     &de_fe1_clk.common,
1006     &de_mp_clk.common,
1007     &tcon0_ch0_clk.common,
1008     &tcon1_ch0_clk.common,
1009     &csi_sclk_clk.common,
1010     &tvd_sun4i_clk.common,
1011     &tvd_sclk1_sun7i_clk.common,
1012     &tvd_sclk2_sun7i_clk.common,
1013     &tcon0_ch1_sclk2_clk.common,
1014     &tcon0_ch1_clk.common,
1015     &tcon1_ch1_sclk2_clk.common,
1016     &tcon1_ch1_clk.common,
1017     &csi0_clk.common,
1018     &csi1_clk.common,
1019     &ve_clk.common,
1020     &codec_clk.common,
1021     &avs_clk.common,
1022     &ace_clk.common,
1023     &hdmi_clk.common,
1024     &gpu_sun4i_clk.common,
1025     &gpu_sun7i_clk.common,
1026     &mbus_sun4i_clk.common,
1027     &mbus_sun7i_clk.common,
1028     &hdmi1_slow_clk.common,
1029     &hdmi1_clk.common,
1030     &out_a_clk.common,
1031     &out_b_clk.common
1032 };
1033 
1034 static const struct clk_hw *clk_parent_pll_audio[] = {
1035     &pll_audio_base_clk.common.hw
1036 };
1037 
1038 /* Post-divider for pll-audio is hardcoded to 1 */
1039 static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
1040                 clk_parent_pll_audio,
1041                 1, 1, CLK_SET_RATE_PARENT);
1042 static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
1043                 clk_parent_pll_audio,
1044                 2, 1, CLK_SET_RATE_PARENT);
1045 static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
1046                 clk_parent_pll_audio,
1047                 1, 1, CLK_SET_RATE_PARENT);
1048 static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
1049                 clk_parent_pll_audio,
1050                 1, 2, CLK_SET_RATE_PARENT);
1051 static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
1052                &pll_video0_clk.common.hw,
1053                1, 2, CLK_SET_RATE_PARENT);
1054 static CLK_FIXED_FACTOR_HW(pll_video1_2x_clk, "pll-video1-2x",
1055                &pll_video1_clk.common.hw,
1056                1, 2, CLK_SET_RATE_PARENT);
1057 
1058 
1059 static struct clk_hw_onecell_data sun4i_a10_hw_clks = {
1060     .hws    = {
1061         [CLK_HOSC]      = &hosc_clk.common.hw,
1062         [CLK_PLL_CORE]      = &pll_core_clk.common.hw,
1063         [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
1064         [CLK_PLL_AUDIO]     = &pll_audio_clk.hw,
1065         [CLK_PLL_AUDIO_2X]  = &pll_audio_2x_clk.hw,
1066         [CLK_PLL_AUDIO_4X]  = &pll_audio_4x_clk.hw,
1067         [CLK_PLL_AUDIO_8X]  = &pll_audio_8x_clk.hw,
1068         [CLK_PLL_VIDEO0]    = &pll_video0_clk.common.hw,
1069         [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
1070         [CLK_PLL_VE]        = &pll_ve_sun4i_clk.common.hw,
1071         [CLK_PLL_DDR_BASE]  = &pll_ddr_base_clk.common.hw,
1072         [CLK_PLL_DDR]       = &pll_ddr_clk.common.hw,
1073         [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
1074         [CLK_PLL_PERIPH_BASE]   = &pll_periph_base_clk.common.hw,
1075         [CLK_PLL_PERIPH]    = &pll_periph_clk.hw,
1076         [CLK_PLL_PERIPH_SATA]   = &pll_periph_sata_clk.common.hw,
1077         [CLK_PLL_VIDEO1]    = &pll_video1_clk.common.hw,
1078         [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
1079         [CLK_CPU]       = &cpu_clk.common.hw,
1080         [CLK_AXI]       = &axi_clk.common.hw,
1081         [CLK_AXI_DRAM]      = &axi_dram_clk.common.hw,
1082         [CLK_AHB]       = &ahb_sun4i_clk.common.hw,
1083         [CLK_APB0]      = &apb0_clk.common.hw,
1084         [CLK_APB1]      = &apb1_clk.common.hw,
1085         [CLK_AHB_OTG]       = &ahb_otg_clk.common.hw,
1086         [CLK_AHB_EHCI0]     = &ahb_ehci0_clk.common.hw,
1087         [CLK_AHB_OHCI0]     = &ahb_ohci0_clk.common.hw,
1088         [CLK_AHB_EHCI1]     = &ahb_ehci1_clk.common.hw,
1089         [CLK_AHB_OHCI1]     = &ahb_ohci1_clk.common.hw,
1090         [CLK_AHB_SS]        = &ahb_ss_clk.common.hw,
1091         [CLK_AHB_DMA]       = &ahb_dma_clk.common.hw,
1092         [CLK_AHB_BIST]      = &ahb_bist_clk.common.hw,
1093         [CLK_AHB_MMC0]      = &ahb_mmc0_clk.common.hw,
1094         [CLK_AHB_MMC1]      = &ahb_mmc1_clk.common.hw,
1095         [CLK_AHB_MMC2]      = &ahb_mmc2_clk.common.hw,
1096         [CLK_AHB_MMC3]      = &ahb_mmc3_clk.common.hw,
1097         [CLK_AHB_MS]        = &ahb_ms_clk.common.hw,
1098         [CLK_AHB_NAND]      = &ahb_nand_clk.common.hw,
1099         [CLK_AHB_SDRAM]     = &ahb_sdram_clk.common.hw,
1100         [CLK_AHB_ACE]       = &ahb_ace_clk.common.hw,
1101         [CLK_AHB_EMAC]      = &ahb_emac_clk.common.hw,
1102         [CLK_AHB_TS]        = &ahb_ts_clk.common.hw,
1103         [CLK_AHB_SPI0]      = &ahb_spi0_clk.common.hw,
1104         [CLK_AHB_SPI1]      = &ahb_spi1_clk.common.hw,
1105         [CLK_AHB_SPI2]      = &ahb_spi2_clk.common.hw,
1106         [CLK_AHB_SPI3]      = &ahb_spi3_clk.common.hw,
1107         [CLK_AHB_PATA]      = &ahb_pata_clk.common.hw,
1108         [CLK_AHB_SATA]      = &ahb_sata_clk.common.hw,
1109         [CLK_AHB_GPS]       = &ahb_gps_clk.common.hw,
1110         [CLK_AHB_VE]        = &ahb_ve_clk.common.hw,
1111         [CLK_AHB_TVD]       = &ahb_tvd_clk.common.hw,
1112         [CLK_AHB_TVE0]      = &ahb_tve0_clk.common.hw,
1113         [CLK_AHB_TVE1]      = &ahb_tve1_clk.common.hw,
1114         [CLK_AHB_LCD0]      = &ahb_lcd0_clk.common.hw,
1115         [CLK_AHB_LCD1]      = &ahb_lcd1_clk.common.hw,
1116         [CLK_AHB_CSI0]      = &ahb_csi0_clk.common.hw,
1117         [CLK_AHB_CSI1]      = &ahb_csi1_clk.common.hw,
1118         [CLK_AHB_HDMI0]     = &ahb_hdmi0_clk.common.hw,
1119         [CLK_AHB_DE_BE0]    = &ahb_de_be0_clk.common.hw,
1120         [CLK_AHB_DE_BE1]    = &ahb_de_be1_clk.common.hw,
1121         [CLK_AHB_DE_FE0]    = &ahb_de_fe0_clk.common.hw,
1122         [CLK_AHB_DE_FE1]    = &ahb_de_fe1_clk.common.hw,
1123         [CLK_AHB_MP]        = &ahb_mp_clk.common.hw,
1124         [CLK_AHB_GPU]       = &ahb_gpu_clk.common.hw,
1125         [CLK_APB0_CODEC]    = &apb0_codec_clk.common.hw,
1126         [CLK_APB0_SPDIF]    = &apb0_spdif_clk.common.hw,
1127         [CLK_APB0_AC97]     = &apb0_ac97_clk.common.hw,
1128         [CLK_APB0_I2S0]     = &apb0_i2s0_clk.common.hw,
1129         [CLK_APB0_PIO]      = &apb0_pio_clk.common.hw,
1130         [CLK_APB0_IR0]      = &apb0_ir0_clk.common.hw,
1131         [CLK_APB0_IR1]      = &apb0_ir1_clk.common.hw,
1132         [CLK_APB0_KEYPAD]   = &apb0_keypad_clk.common.hw,
1133         [CLK_APB1_I2C0]     = &apb1_i2c0_clk.common.hw,
1134         [CLK_APB1_I2C1]     = &apb1_i2c1_clk.common.hw,
1135         [CLK_APB1_I2C2]     = &apb1_i2c2_clk.common.hw,
1136         [CLK_APB1_CAN]      = &apb1_can_clk.common.hw,
1137         [CLK_APB1_SCR]      = &apb1_scr_clk.common.hw,
1138         [CLK_APB1_PS20]     = &apb1_ps20_clk.common.hw,
1139         [CLK_APB1_PS21]     = &apb1_ps21_clk.common.hw,
1140         [CLK_APB1_UART0]    = &apb1_uart0_clk.common.hw,
1141         [CLK_APB1_UART1]    = &apb1_uart1_clk.common.hw,
1142         [CLK_APB1_UART2]    = &apb1_uart2_clk.common.hw,
1143         [CLK_APB1_UART3]    = &apb1_uart3_clk.common.hw,
1144         [CLK_APB1_UART4]    = &apb1_uart4_clk.common.hw,
1145         [CLK_APB1_UART5]    = &apb1_uart5_clk.common.hw,
1146         [CLK_APB1_UART6]    = &apb1_uart6_clk.common.hw,
1147         [CLK_APB1_UART7]    = &apb1_uart7_clk.common.hw,
1148         [CLK_NAND]      = &nand_clk.common.hw,
1149         [CLK_MS]        = &ms_clk.common.hw,
1150         [CLK_MMC0]      = &mmc0_clk.common.hw,
1151         [CLK_MMC1]      = &mmc1_clk.common.hw,
1152         [CLK_MMC2]      = &mmc2_clk.common.hw,
1153         [CLK_MMC3]      = &mmc3_clk.common.hw,
1154         [CLK_TS]        = &ts_clk.common.hw,
1155         [CLK_SS]        = &ss_clk.common.hw,
1156         [CLK_SPI0]      = &spi0_clk.common.hw,
1157         [CLK_SPI1]      = &spi1_clk.common.hw,
1158         [CLK_SPI2]      = &spi2_clk.common.hw,
1159         [CLK_PATA]      = &pata_clk.common.hw,
1160         [CLK_IR0]       = &ir0_sun4i_clk.common.hw,
1161         [CLK_IR1]       = &ir1_sun4i_clk.common.hw,
1162         [CLK_I2S0]      = &i2s0_clk.common.hw,
1163         [CLK_AC97]      = &ac97_clk.common.hw,
1164         [CLK_SPDIF]     = &spdif_clk.common.hw,
1165         [CLK_KEYPAD]        = &keypad_clk.common.hw,
1166         [CLK_SATA]      = &sata_clk.common.hw,
1167         [CLK_USB_OHCI0]     = &usb_ohci0_clk.common.hw,
1168         [CLK_USB_OHCI1]     = &usb_ohci1_clk.common.hw,
1169         [CLK_USB_PHY]       = &usb_phy_clk.common.hw,
1170         /* CLK_GPS is unimplemented */
1171         [CLK_SPI3]      = &spi3_clk.common.hw,
1172         [CLK_DRAM_VE]       = &dram_ve_clk.common.hw,
1173         [CLK_DRAM_CSI0]     = &dram_csi0_clk.common.hw,
1174         [CLK_DRAM_CSI1]     = &dram_csi1_clk.common.hw,
1175         [CLK_DRAM_TS]       = &dram_ts_clk.common.hw,
1176         [CLK_DRAM_TVD]      = &dram_tvd_clk.common.hw,
1177         [CLK_DRAM_TVE0]     = &dram_tve0_clk.common.hw,
1178         [CLK_DRAM_TVE1]     = &dram_tve1_clk.common.hw,
1179         [CLK_DRAM_OUT]      = &dram_out_clk.common.hw,
1180         [CLK_DRAM_DE_FE1]   = &dram_de_fe1_clk.common.hw,
1181         [CLK_DRAM_DE_FE0]   = &dram_de_fe0_clk.common.hw,
1182         [CLK_DRAM_DE_BE0]   = &dram_de_be0_clk.common.hw,
1183         [CLK_DRAM_DE_BE1]   = &dram_de_be1_clk.common.hw,
1184         [CLK_DRAM_MP]       = &dram_mp_clk.common.hw,
1185         [CLK_DRAM_ACE]      = &dram_ace_clk.common.hw,
1186         [CLK_DE_BE0]        = &de_be0_clk.common.hw,
1187         [CLK_DE_BE1]        = &de_be1_clk.common.hw,
1188         [CLK_DE_FE0]        = &de_fe0_clk.common.hw,
1189         [CLK_DE_FE1]        = &de_fe1_clk.common.hw,
1190         [CLK_DE_MP]     = &de_mp_clk.common.hw,
1191         [CLK_TCON0_CH0]     = &tcon0_ch0_clk.common.hw,
1192         [CLK_TCON1_CH0]     = &tcon1_ch0_clk.common.hw,
1193         [CLK_CSI_SCLK]      = &csi_sclk_clk.common.hw,
1194         [CLK_TVD]       = &tvd_sun4i_clk.common.hw,
1195         [CLK_TCON0_CH1_SCLK2]   = &tcon0_ch1_sclk2_clk.common.hw,
1196         [CLK_TCON0_CH1]     = &tcon0_ch1_clk.common.hw,
1197         [CLK_TCON1_CH1_SCLK2]   = &tcon1_ch1_sclk2_clk.common.hw,
1198         [CLK_TCON1_CH1]     = &tcon1_ch1_clk.common.hw,
1199         [CLK_CSI0]      = &csi0_clk.common.hw,
1200         [CLK_CSI1]      = &csi1_clk.common.hw,
1201         [CLK_VE]        = &ve_clk.common.hw,
1202         [CLK_CODEC]     = &codec_clk.common.hw,
1203         [CLK_AVS]       = &avs_clk.common.hw,
1204         [CLK_ACE]       = &ace_clk.common.hw,
1205         [CLK_HDMI]      = &hdmi_clk.common.hw,
1206         [CLK_GPU]       = &gpu_sun7i_clk.common.hw,
1207         [CLK_MBUS]      = &mbus_sun4i_clk.common.hw,
1208     },
1209     .num    = CLK_NUMBER_SUN4I,
1210 };
1211 static struct clk_hw_onecell_data sun7i_a20_hw_clks = {
1212     .hws    = {
1213         [CLK_HOSC]      = &hosc_clk.common.hw,
1214         [CLK_PLL_CORE]      = &pll_core_clk.common.hw,
1215         [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
1216         [CLK_PLL_AUDIO]     = &pll_audio_clk.hw,
1217         [CLK_PLL_AUDIO_2X]  = &pll_audio_2x_clk.hw,
1218         [CLK_PLL_AUDIO_4X]  = &pll_audio_4x_clk.hw,
1219         [CLK_PLL_AUDIO_8X]  = &pll_audio_8x_clk.hw,
1220         [CLK_PLL_VIDEO0]    = &pll_video0_clk.common.hw,
1221         [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
1222         [CLK_PLL_VE]        = &pll_ve_sun7i_clk.common.hw,
1223         [CLK_PLL_DDR_BASE]  = &pll_ddr_base_clk.common.hw,
1224         [CLK_PLL_DDR]       = &pll_ddr_clk.common.hw,
1225         [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
1226         [CLK_PLL_PERIPH_BASE]   = &pll_periph_base_clk.common.hw,
1227         [CLK_PLL_PERIPH]    = &pll_periph_clk.hw,
1228         [CLK_PLL_PERIPH_SATA]   = &pll_periph_sata_clk.common.hw,
1229         [CLK_PLL_VIDEO1]    = &pll_video1_clk.common.hw,
1230         [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
1231         [CLK_PLL_GPU]       = &pll_gpu_clk.common.hw,
1232         [CLK_CPU]       = &cpu_clk.common.hw,
1233         [CLK_AXI]       = &axi_clk.common.hw,
1234         [CLK_AHB]       = &ahb_sun7i_clk.common.hw,
1235         [CLK_APB0]      = &apb0_clk.common.hw,
1236         [CLK_APB1]      = &apb1_clk.common.hw,
1237         [CLK_AHB_OTG]       = &ahb_otg_clk.common.hw,
1238         [CLK_AHB_EHCI0]     = &ahb_ehci0_clk.common.hw,
1239         [CLK_AHB_OHCI0]     = &ahb_ohci0_clk.common.hw,
1240         [CLK_AHB_EHCI1]     = &ahb_ehci1_clk.common.hw,
1241         [CLK_AHB_OHCI1]     = &ahb_ohci1_clk.common.hw,
1242         [CLK_AHB_SS]        = &ahb_ss_clk.common.hw,
1243         [CLK_AHB_DMA]       = &ahb_dma_clk.common.hw,
1244         [CLK_AHB_BIST]      = &ahb_bist_clk.common.hw,
1245         [CLK_AHB_MMC0]      = &ahb_mmc0_clk.common.hw,
1246         [CLK_AHB_MMC1]      = &ahb_mmc1_clk.common.hw,
1247         [CLK_AHB_MMC2]      = &ahb_mmc2_clk.common.hw,
1248         [CLK_AHB_MMC3]      = &ahb_mmc3_clk.common.hw,
1249         [CLK_AHB_MS]        = &ahb_ms_clk.common.hw,
1250         [CLK_AHB_NAND]      = &ahb_nand_clk.common.hw,
1251         [CLK_AHB_SDRAM]     = &ahb_sdram_clk.common.hw,
1252         [CLK_AHB_ACE]       = &ahb_ace_clk.common.hw,
1253         [CLK_AHB_EMAC]      = &ahb_emac_clk.common.hw,
1254         [CLK_AHB_TS]        = &ahb_ts_clk.common.hw,
1255         [CLK_AHB_SPI0]      = &ahb_spi0_clk.common.hw,
1256         [CLK_AHB_SPI1]      = &ahb_spi1_clk.common.hw,
1257         [CLK_AHB_SPI2]      = &ahb_spi2_clk.common.hw,
1258         [CLK_AHB_SPI3]      = &ahb_spi3_clk.common.hw,
1259         [CLK_AHB_PATA]      = &ahb_pata_clk.common.hw,
1260         [CLK_AHB_SATA]      = &ahb_sata_clk.common.hw,
1261         [CLK_AHB_HSTIMER]   = &ahb_hstimer_clk.common.hw,
1262         [CLK_AHB_VE]        = &ahb_ve_clk.common.hw,
1263         [CLK_AHB_TVD]       = &ahb_tvd_clk.common.hw,
1264         [CLK_AHB_TVE0]      = &ahb_tve0_clk.common.hw,
1265         [CLK_AHB_TVE1]      = &ahb_tve1_clk.common.hw,
1266         [CLK_AHB_LCD0]      = &ahb_lcd0_clk.common.hw,
1267         [CLK_AHB_LCD1]      = &ahb_lcd1_clk.common.hw,
1268         [CLK_AHB_CSI0]      = &ahb_csi0_clk.common.hw,
1269         [CLK_AHB_CSI1]      = &ahb_csi1_clk.common.hw,
1270         [CLK_AHB_HDMI1]     = &ahb_hdmi1_clk.common.hw,
1271         [CLK_AHB_HDMI0]     = &ahb_hdmi0_clk.common.hw,
1272         [CLK_AHB_DE_BE0]    = &ahb_de_be0_clk.common.hw,
1273         [CLK_AHB_DE_BE1]    = &ahb_de_be1_clk.common.hw,
1274         [CLK_AHB_DE_FE0]    = &ahb_de_fe0_clk.common.hw,
1275         [CLK_AHB_DE_FE1]    = &ahb_de_fe1_clk.common.hw,
1276         [CLK_AHB_GMAC]      = &ahb_gmac_clk.common.hw,
1277         [CLK_AHB_MP]        = &ahb_mp_clk.common.hw,
1278         [CLK_AHB_GPU]       = &ahb_gpu_clk.common.hw,
1279         [CLK_APB0_CODEC]    = &apb0_codec_clk.common.hw,
1280         [CLK_APB0_SPDIF]    = &apb0_spdif_clk.common.hw,
1281         [CLK_APB0_AC97]     = &apb0_ac97_clk.common.hw,
1282         [CLK_APB0_I2S0]     = &apb0_i2s0_clk.common.hw,
1283         [CLK_APB0_I2S1]     = &apb0_i2s1_clk.common.hw,
1284         [CLK_APB0_PIO]      = &apb0_pio_clk.common.hw,
1285         [CLK_APB0_IR0]      = &apb0_ir0_clk.common.hw,
1286         [CLK_APB0_IR1]      = &apb0_ir1_clk.common.hw,
1287         [CLK_APB0_I2S2]     = &apb0_i2s2_clk.common.hw,
1288         [CLK_APB0_KEYPAD]   = &apb0_keypad_clk.common.hw,
1289         [CLK_APB1_I2C0]     = &apb1_i2c0_clk.common.hw,
1290         [CLK_APB1_I2C1]     = &apb1_i2c1_clk.common.hw,
1291         [CLK_APB1_I2C2]     = &apb1_i2c2_clk.common.hw,
1292         [CLK_APB1_I2C3]     = &apb1_i2c3_clk.common.hw,
1293         [CLK_APB1_CAN]      = &apb1_can_clk.common.hw,
1294         [CLK_APB1_SCR]      = &apb1_scr_clk.common.hw,
1295         [CLK_APB1_PS20]     = &apb1_ps20_clk.common.hw,
1296         [CLK_APB1_PS21]     = &apb1_ps21_clk.common.hw,
1297         [CLK_APB1_I2C4]     = &apb1_i2c4_clk.common.hw,
1298         [CLK_APB1_UART0]    = &apb1_uart0_clk.common.hw,
1299         [CLK_APB1_UART1]    = &apb1_uart1_clk.common.hw,
1300         [CLK_APB1_UART2]    = &apb1_uart2_clk.common.hw,
1301         [CLK_APB1_UART3]    = &apb1_uart3_clk.common.hw,
1302         [CLK_APB1_UART4]    = &apb1_uart4_clk.common.hw,
1303         [CLK_APB1_UART5]    = &apb1_uart5_clk.common.hw,
1304         [CLK_APB1_UART6]    = &apb1_uart6_clk.common.hw,
1305         [CLK_APB1_UART7]    = &apb1_uart7_clk.common.hw,
1306         [CLK_NAND]      = &nand_clk.common.hw,
1307         [CLK_MS]        = &ms_clk.common.hw,
1308         [CLK_MMC0]      = &mmc0_clk.common.hw,
1309         [CLK_MMC0_OUTPUT]   = &mmc0_output_clk.common.hw,
1310         [CLK_MMC0_SAMPLE]   = &mmc0_sample_clk.common.hw,
1311         [CLK_MMC1]      = &mmc1_clk.common.hw,
1312         [CLK_MMC1_OUTPUT]   = &mmc1_output_clk.common.hw,
1313         [CLK_MMC1_SAMPLE]   = &mmc1_sample_clk.common.hw,
1314         [CLK_MMC2]      = &mmc2_clk.common.hw,
1315         [CLK_MMC2_OUTPUT]   = &mmc2_output_clk.common.hw,
1316         [CLK_MMC2_SAMPLE]   = &mmc2_sample_clk.common.hw,
1317         [CLK_MMC3]      = &mmc3_clk.common.hw,
1318         [CLK_MMC3_OUTPUT]   = &mmc3_output_clk.common.hw,
1319         [CLK_MMC3_SAMPLE]   = &mmc3_sample_clk.common.hw,
1320         [CLK_TS]        = &ts_clk.common.hw,
1321         [CLK_SS]        = &ss_clk.common.hw,
1322         [CLK_SPI0]      = &spi0_clk.common.hw,
1323         [CLK_SPI1]      = &spi1_clk.common.hw,
1324         [CLK_SPI2]      = &spi2_clk.common.hw,
1325         [CLK_PATA]      = &pata_clk.common.hw,
1326         [CLK_IR0]       = &ir0_sun7i_clk.common.hw,
1327         [CLK_IR1]       = &ir1_sun7i_clk.common.hw,
1328         [CLK_I2S0]      = &i2s0_clk.common.hw,
1329         [CLK_AC97]      = &ac97_clk.common.hw,
1330         [CLK_SPDIF]     = &spdif_clk.common.hw,
1331         [CLK_KEYPAD]        = &keypad_clk.common.hw,
1332         [CLK_SATA]      = &sata_clk.common.hw,
1333         [CLK_USB_OHCI0]     = &usb_ohci0_clk.common.hw,
1334         [CLK_USB_OHCI1]     = &usb_ohci1_clk.common.hw,
1335         [CLK_USB_PHY]       = &usb_phy_clk.common.hw,
1336         /* CLK_GPS is unimplemented */
1337         [CLK_SPI3]      = &spi3_clk.common.hw,
1338         [CLK_I2S1]      = &i2s1_clk.common.hw,
1339         [CLK_I2S2]      = &i2s2_clk.common.hw,
1340         [CLK_DRAM_VE]       = &dram_ve_clk.common.hw,
1341         [CLK_DRAM_CSI0]     = &dram_csi0_clk.common.hw,
1342         [CLK_DRAM_CSI1]     = &dram_csi1_clk.common.hw,
1343         [CLK_DRAM_TS]       = &dram_ts_clk.common.hw,
1344         [CLK_DRAM_TVD]      = &dram_tvd_clk.common.hw,
1345         [CLK_DRAM_TVE0]     = &dram_tve0_clk.common.hw,
1346         [CLK_DRAM_TVE1]     = &dram_tve1_clk.common.hw,
1347         [CLK_DRAM_OUT]      = &dram_out_clk.common.hw,
1348         [CLK_DRAM_DE_FE1]   = &dram_de_fe1_clk.common.hw,
1349         [CLK_DRAM_DE_FE0]   = &dram_de_fe0_clk.common.hw,
1350         [CLK_DRAM_DE_BE0]   = &dram_de_be0_clk.common.hw,
1351         [CLK_DRAM_DE_BE1]   = &dram_de_be1_clk.common.hw,
1352         [CLK_DRAM_MP]       = &dram_mp_clk.common.hw,
1353         [CLK_DRAM_ACE]      = &dram_ace_clk.common.hw,
1354         [CLK_DE_BE0]        = &de_be0_clk.common.hw,
1355         [CLK_DE_BE1]        = &de_be1_clk.common.hw,
1356         [CLK_DE_FE0]        = &de_fe0_clk.common.hw,
1357         [CLK_DE_FE1]        = &de_fe1_clk.common.hw,
1358         [CLK_DE_MP]     = &de_mp_clk.common.hw,
1359         [CLK_TCON0_CH0]     = &tcon0_ch0_clk.common.hw,
1360         [CLK_TCON1_CH0]     = &tcon1_ch0_clk.common.hw,
1361         [CLK_CSI_SCLK]      = &csi_sclk_clk.common.hw,
1362         [CLK_TVD_SCLK2]     = &tvd_sclk2_sun7i_clk.common.hw,
1363         [CLK_TVD]       = &tvd_sclk1_sun7i_clk.common.hw,
1364         [CLK_TCON0_CH1_SCLK2]   = &tcon0_ch1_sclk2_clk.common.hw,
1365         [CLK_TCON0_CH1]     = &tcon0_ch1_clk.common.hw,
1366         [CLK_TCON1_CH1_SCLK2]   = &tcon1_ch1_sclk2_clk.common.hw,
1367         [CLK_TCON1_CH1]     = &tcon1_ch1_clk.common.hw,
1368         [CLK_CSI0]      = &csi0_clk.common.hw,
1369         [CLK_CSI1]      = &csi1_clk.common.hw,
1370         [CLK_VE]        = &ve_clk.common.hw,
1371         [CLK_CODEC]     = &codec_clk.common.hw,
1372         [CLK_AVS]       = &avs_clk.common.hw,
1373         [CLK_ACE]       = &ace_clk.common.hw,
1374         [CLK_HDMI]      = &hdmi_clk.common.hw,
1375         [CLK_GPU]       = &gpu_sun7i_clk.common.hw,
1376         [CLK_MBUS]      = &mbus_sun7i_clk.common.hw,
1377         [CLK_HDMI1_SLOW]    = &hdmi1_slow_clk.common.hw,
1378         [CLK_HDMI1]     = &hdmi1_clk.common.hw,
1379         [CLK_OUT_A]     = &out_a_clk.common.hw,
1380         [CLK_OUT_B]     = &out_b_clk.common.hw,
1381     },
1382     .num    = CLK_NUMBER_SUN7I,
1383 };
1384 
1385 static struct ccu_reset_map sunxi_a10_a20_ccu_resets[] = {
1386     [RST_USB_PHY0]      = { 0x0cc, BIT(0) },
1387     [RST_USB_PHY1]      = { 0x0cc, BIT(1) },
1388     [RST_USB_PHY2]      = { 0x0cc, BIT(2) },
1389     [RST_GPS]       = { 0x0d0, BIT(0) },
1390     [RST_DE_BE0]        = { 0x104, BIT(30) },
1391     [RST_DE_BE1]        = { 0x108, BIT(30) },
1392     [RST_DE_FE0]        = { 0x10c, BIT(30) },
1393     [RST_DE_FE1]        = { 0x110, BIT(30) },
1394     [RST_DE_MP]     = { 0x114, BIT(30) },
1395     [RST_TVE0]      = { 0x118, BIT(29) },
1396     [RST_TCON0]     = { 0x118, BIT(30) },
1397     [RST_TVE1]      = { 0x11c, BIT(29) },
1398     [RST_TCON1]     = { 0x11c, BIT(30) },
1399     [RST_CSI0]      = { 0x134, BIT(30) },
1400     [RST_CSI1]      = { 0x138, BIT(30) },
1401     [RST_VE]        = { 0x13c, BIT(0) },
1402     [RST_ACE]       = { 0x148, BIT(16) },
1403     [RST_LVDS]      = { 0x14c, BIT(0) },
1404     [RST_GPU]       = { 0x154, BIT(30) },
1405     [RST_HDMI_H]        = { 0x170, BIT(0) },
1406     [RST_HDMI_SYS]      = { 0x170, BIT(1) },
1407     [RST_HDMI_AUDIO_DMA]    = { 0x170, BIT(2) },
1408 };
1409 
1410 static const struct sunxi_ccu_desc sun4i_a10_ccu_desc = {
1411     .ccu_clks   = sun4i_sun7i_ccu_clks,
1412     .num_ccu_clks   = ARRAY_SIZE(sun4i_sun7i_ccu_clks),
1413 
1414     .hw_clks    = &sun4i_a10_hw_clks,
1415 
1416     .resets     = sunxi_a10_a20_ccu_resets,
1417     .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
1418 };
1419 
1420 static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = {
1421     .ccu_clks   = sun4i_sun7i_ccu_clks,
1422     .num_ccu_clks   = ARRAY_SIZE(sun4i_sun7i_ccu_clks),
1423 
1424     .hw_clks    = &sun7i_a20_hw_clks,
1425 
1426     .resets     = sunxi_a10_a20_ccu_resets,
1427     .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
1428 };
1429 
1430 static int sun4i_a10_ccu_probe(struct platform_device *pdev)
1431 {
1432     const struct sunxi_ccu_desc *desc;
1433     void __iomem *reg;
1434     u32 val;
1435 
1436     desc = of_device_get_match_data(&pdev->dev);
1437     if (!desc)
1438         return -EINVAL;
1439 
1440     reg = devm_platform_ioremap_resource(pdev, 0);
1441     if (IS_ERR(reg))
1442         return PTR_ERR(reg);
1443 
1444     val = readl(reg + SUN4I_PLL_AUDIO_REG);
1445 
1446     /*
1447      * Force VCO and PLL bias current to lowest setting. Higher
1448      * settings interfere with sigma-delta modulation and result
1449      * in audible noise and distortions when using SPDIF or I2S.
1450      */
1451     val &= ~GENMASK(25, 16);
1452 
1453     /* Force the PLL-Audio-1x divider to 1 */
1454     val &= ~GENMASK(29, 26);
1455     writel(val | (1 << 26), reg + SUN4I_PLL_AUDIO_REG);
1456 
1457     /*
1458      * Use the peripheral PLL6 as the AHB parent, instead of CPU /
1459      * AXI which have rate changes due to cpufreq.
1460      *
1461      * This is especially a big deal for the HS timer whose parent
1462      * clock is AHB.
1463      *
1464      * NB! These bits are undocumented in A10 manual.
1465      */
1466     val = readl(reg + SUN4I_AHB_REG);
1467     val &= ~GENMASK(7, 6);
1468     writel(val | (2 << 6), reg + SUN4I_AHB_REG);
1469 
1470     return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
1471 }
1472 
1473 static const struct of_device_id sun4i_a10_ccu_ids[] = {
1474     {
1475         .compatible = "allwinner,sun4i-a10-ccu",
1476         .data = &sun4i_a10_ccu_desc,
1477     },
1478     {
1479         .compatible = "allwinner,sun7i-a20-ccu",
1480         .data = &sun7i_a20_ccu_desc,
1481     },
1482     { }
1483 };
1484 
1485 static struct platform_driver sun4i_a10_ccu_driver = {
1486     .probe  = sun4i_a10_ccu_probe,
1487     .driver = {
1488         .name           = "sun4i-a10-ccu",
1489         .suppress_bind_attrs    = true,
1490         .of_match_table     = sun4i_a10_ccu_ids,
1491     },
1492 };
1493 module_platform_driver(sun4i_a10_ccu_driver);
1494 
1495 MODULE_IMPORT_NS(SUNXI_CCU);
1496 MODULE_LICENSE("GPL");