Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
0004  */
0005 
0006 #include <linux/clk-provider.h>
0007 #include <linux/io.h>
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010 
0011 #include "ccu_common.h"
0012 #include "ccu_reset.h"
0013 
0014 #include "ccu_div.h"
0015 #include "ccu_gate.h"
0016 #include "ccu_mp.h"
0017 #include "ccu_mux.h"
0018 #include "ccu_nkmp.h"
0019 #include "ccu_nm.h"
0020 #include "ccu_phase.h"
0021 
0022 #include "ccu-sun8i-a83t.h"
0023 
0024 #define CCU_SUN8I_A83T_LOCK_REG 0x20c
0025 
0026 /*
0027  * The CPU PLLs are actually NP clocks, with P being /1 or /4. However
0028  * P should only be used for output frequencies lower than 228 MHz.
0029  * Neither mainline Linux, U-boot, nor the vendor BSPs use these.
0030  *
0031  * For now we can just model it as a multiplier clock, and force P to /1.
0032  */
0033 #define SUN8I_A83T_PLL_C0CPUX_REG   0x000
0034 #define SUN8I_A83T_PLL_C1CPUX_REG   0x004
0035 
0036 static struct ccu_mult pll_c0cpux_clk = {
0037     .enable     = BIT(31),
0038     .lock       = BIT(0),
0039     .mult       = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0040     .common     = {
0041         .reg        = SUN8I_A83T_PLL_C0CPUX_REG,
0042         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0043         .features   = CCU_FEATURE_LOCK_REG,
0044         .hw.init    = CLK_HW_INIT("pll-c0cpux", "osc24M",
0045                           &ccu_mult_ops,
0046                           CLK_SET_RATE_UNGATE),
0047     },
0048 };
0049 
0050 static struct ccu_mult pll_c1cpux_clk = {
0051     .enable     = BIT(31),
0052     .lock       = BIT(1),
0053     .mult       = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0054     .common     = {
0055         .reg        = SUN8I_A83T_PLL_C1CPUX_REG,
0056         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0057         .features   = CCU_FEATURE_LOCK_REG,
0058         .hw.init    = CLK_HW_INIT("pll-c1cpux", "osc24M",
0059                           &ccu_mult_ops,
0060                           CLK_SET_RATE_UNGATE),
0061     },
0062 };
0063 
0064 /*
0065  * The Audio PLL has d1, d2 dividers in addition to the usual N, M
0066  * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
0067  * and 24.576 MHz, ignore them for now. Enforce the default for them,
0068  * which is d1 = 0, d2 = 1.
0069  */
0070 #define SUN8I_A83T_PLL_AUDIO_REG    0x008
0071 
0072 /* clock rates doubled for post divider */
0073 static struct ccu_sdm_setting pll_audio_sdm_table[] = {
0074     { .rate = 45158400, .pattern = 0xc00121ff, .m = 29, .n = 54 },
0075     { .rate = 49152000, .pattern = 0xc000e147, .m = 30, .n = 61 },
0076 };
0077 
0078 static struct ccu_nm pll_audio_clk = {
0079     .enable     = BIT(31),
0080     .lock       = BIT(2),
0081     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0082     .m      = _SUNXI_CCU_DIV(0, 6),
0083     .fixed_post_div = 2,
0084     .sdm        = _SUNXI_CCU_SDM(pll_audio_sdm_table, BIT(24),
0085                      0x284, BIT(31)),
0086     .common     = {
0087         .reg        = SUN8I_A83T_PLL_AUDIO_REG,
0088         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0089         .features   = CCU_FEATURE_LOCK_REG |
0090                   CCU_FEATURE_FIXED_POSTDIV |
0091                   CCU_FEATURE_SIGMA_DELTA_MOD,
0092         .hw.init    = CLK_HW_INIT("pll-audio", "osc24M",
0093                           &ccu_nm_ops, CLK_SET_RATE_UNGATE),
0094     },
0095 };
0096 
0097 /* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
0098 static struct ccu_nkmp pll_video0_clk = {
0099     .enable     = BIT(31),
0100     .lock       = BIT(3),
0101     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0102     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0103     .p      = _SUNXI_CCU_DIV(0, 2), /* output divider */
0104     .max_rate   = 3000000000UL,
0105     .common     = {
0106         .reg        = 0x010,
0107         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0108         .features   = CCU_FEATURE_LOCK_REG,
0109         .hw.init    = CLK_HW_INIT("pll-video0", "osc24M",
0110                           &ccu_nkmp_ops,
0111                           CLK_SET_RATE_UNGATE),
0112     },
0113 };
0114 
0115 static struct ccu_nkmp pll_ve_clk = {
0116     .enable     = BIT(31),
0117     .lock       = BIT(4),
0118     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0119     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0120     .p      = _SUNXI_CCU_DIV(18, 1), /* output divider */
0121     .common     = {
0122         .reg        = 0x018,
0123         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0124         .features   = CCU_FEATURE_LOCK_REG,
0125         .hw.init    = CLK_HW_INIT("pll-ve", "osc24M",
0126                           &ccu_nkmp_ops,
0127                           CLK_SET_RATE_UNGATE),
0128     },
0129 };
0130 
0131 static struct ccu_nkmp pll_ddr_clk = {
0132     .enable     = BIT(31),
0133     .lock       = BIT(5),
0134     .n      = _SUNXI_CCU_MULT_MIN(8, 8, 12),
0135     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0136     .p      = _SUNXI_CCU_DIV(18, 1), /* output divider */
0137     .common     = {
0138         .reg        = 0x020,
0139         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0140         .features   = CCU_FEATURE_LOCK_REG,
0141         .hw.init    = CLK_HW_INIT("pll-ddr", "osc24M",
0142                           &ccu_nkmp_ops,
0143                           CLK_SET_RATE_UNGATE),
0144     },
0145 };
0146 
0147 static struct ccu_nkmp pll_periph_clk = {
0148     .enable     = BIT(31),
0149     .lock       = BIT(6),
0150     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0151     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0152     .p      = _SUNXI_CCU_DIV(18, 1), /* output divider */
0153     .common     = {
0154         .reg        = 0x028,
0155         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0156         .features   = CCU_FEATURE_LOCK_REG,
0157         .hw.init    = CLK_HW_INIT("pll-periph", "osc24M",
0158                           &ccu_nkmp_ops,
0159                           CLK_SET_RATE_UNGATE),
0160     },
0161 };
0162 
0163 static struct ccu_nkmp pll_gpu_clk = {
0164     .enable     = BIT(31),
0165     .lock       = BIT(7),
0166     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0167     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0168     .p      = _SUNXI_CCU_DIV(18, 1), /* output divider */
0169     .common     = {
0170         .reg        = 0x038,
0171         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0172         .features   = CCU_FEATURE_LOCK_REG,
0173         .hw.init    = CLK_HW_INIT("pll-gpu", "osc24M",
0174                           &ccu_nkmp_ops,
0175                           CLK_SET_RATE_UNGATE),
0176     },
0177 };
0178 
0179 static struct ccu_nkmp pll_hsic_clk = {
0180     .enable     = BIT(31),
0181     .lock       = BIT(8),
0182     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0183     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0184     .p      = _SUNXI_CCU_DIV(18, 1), /* output divider */
0185     .common     = {
0186         .reg        = 0x044,
0187         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0188         .features   = CCU_FEATURE_LOCK_REG,
0189         .hw.init    = CLK_HW_INIT("pll-hsic", "osc24M",
0190                           &ccu_nkmp_ops,
0191                           CLK_SET_RATE_UNGATE),
0192     },
0193 };
0194 
0195 static struct ccu_nkmp pll_de_clk = {
0196     .enable     = BIT(31),
0197     .lock       = BIT(9),
0198     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0199     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0200     .p      = _SUNXI_CCU_DIV(18, 1), /* output divider */
0201     .common     = {
0202         .reg        = 0x048,
0203         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0204         .features   = CCU_FEATURE_LOCK_REG,
0205         .hw.init    = CLK_HW_INIT("pll-de", "osc24M",
0206                           &ccu_nkmp_ops,
0207                           CLK_SET_RATE_UNGATE),
0208     },
0209 };
0210 
0211 static struct ccu_nkmp pll_video1_clk = {
0212     .enable     = BIT(31),
0213     .lock       = BIT(10),
0214     .n      = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
0215     .m      = _SUNXI_CCU_DIV(16, 1), /* input divider */
0216     .p      = _SUNXI_CCU_DIV(0, 2), /* external divider p */
0217     .max_rate   = 3000000000UL,
0218     .common     = {
0219         .reg        = 0x04c,
0220         .lock_reg   = CCU_SUN8I_A83T_LOCK_REG,
0221         .features   = CCU_FEATURE_LOCK_REG,
0222         .hw.init    = CLK_HW_INIT("pll-video1", "osc24M",
0223                           &ccu_nkmp_ops,
0224                           CLK_SET_RATE_UNGATE),
0225     },
0226 };
0227 
0228 static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" };
0229 static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents,
0230              0x50, 12, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
0231 
0232 static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" };
0233 static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents,
0234              0x50, 28, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
0235 
0236 static SUNXI_CCU_M(axi0_clk, "axi0", "c0cpux", 0x050, 0, 2, 0);
0237 static SUNXI_CCU_M(axi1_clk, "axi1", "c1cpux", 0x050, 16, 2, 0);
0238 
0239 static const char * const ahb1_parents[] = { "osc16M-d512", "osc24M",
0240                          "pll-periph",
0241                          "pll-periph" };
0242 static const struct ccu_mux_var_prediv ahb1_predivs[] = {
0243     { .index = 2, .shift = 6, .width = 2 },
0244     { .index = 3, .shift = 6, .width = 2 },
0245 };
0246 static struct ccu_div ahb1_clk = {
0247     .div        = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
0248     .mux        = {
0249         .shift  = 12,
0250         .width  = 2,
0251 
0252         .var_predivs    = ahb1_predivs,
0253         .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
0254     },
0255     .common     = {
0256         .reg        = 0x054,
0257         .hw.init    = CLK_HW_INIT_PARENTS("ahb1",
0258                               ahb1_parents,
0259                               &ccu_div_ops,
0260                               0),
0261     },
0262 };
0263 
0264 static SUNXI_CCU_M(apb1_clk, "apb1", "ahb1", 0x054, 8, 2, 0);
0265 
0266 static const char * const apb2_parents[] = { "osc16M-d512", "osc24M",
0267                          "pll-periph", "pll-periph" };
0268 
0269 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
0270                  0, 5,  /* M */
0271                  16, 2, /* P */
0272                  24, 2, /* mux */
0273                  0);
0274 
0275 static const char * const ahb2_parents[] = { "ahb1", "pll-periph" };
0276 static const struct ccu_mux_fixed_prediv ahb2_prediv = {
0277     .index = 1, .div = 2
0278 };
0279 static struct ccu_mux ahb2_clk = {
0280     .mux        = {
0281         .shift      = 0,
0282         .width      = 2,
0283         .fixed_predivs  = &ahb2_prediv,
0284         .n_predivs  = 1,
0285     },
0286     .common     = {
0287         .reg        = 0x05c,
0288         .hw.init    = CLK_HW_INIT_PARENTS("ahb2",
0289                               ahb2_parents,
0290                               &ccu_mux_ops,
0291                               0),
0292     },
0293 };
0294 
0295 static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
0296               0x060, BIT(1), 0);
0297 static SUNXI_CCU_GATE(bus_ss_clk,   "bus-ss",   "ahb1",
0298               0x060, BIT(5), 0);
0299 static SUNXI_CCU_GATE(bus_dma_clk,  "bus-dma",  "ahb1",
0300               0x060, BIT(6), 0);
0301 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
0302               0x060, BIT(8), 0);
0303 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
0304               0x060, BIT(9), 0);
0305 static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
0306               0x060, BIT(10), 0);
0307 static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
0308               0x060, BIT(13), 0);
0309 static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
0310               0x060, BIT(14), 0);
0311 static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb2",
0312               0x060, BIT(17), 0);
0313 static SUNXI_CCU_GATE(bus_hstimer_clk,  "bus-hstimer",  "ahb1",
0314               0x060, BIT(19), 0);
0315 static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
0316               0x060, BIT(20), 0);
0317 static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
0318               0x060, BIT(21), 0);
0319 static SUNXI_CCU_GATE(bus_otg_clk,  "bus-otg",  "ahb1",
0320               0x060, BIT(24), 0);
0321 static SUNXI_CCU_GATE(bus_ehci0_clk,    "bus-ehci0",    "ahb2",
0322               0x060, BIT(26), 0);
0323 static SUNXI_CCU_GATE(bus_ehci1_clk,    "bus-ehci1",    "ahb2",
0324               0x060, BIT(27), 0);
0325 static SUNXI_CCU_GATE(bus_ohci0_clk,    "bus-ohci0",    "ahb2",
0326               0x060, BIT(29), 0);
0327 
0328 static SUNXI_CCU_GATE(bus_ve_clk,   "bus-ve",   "ahb1",
0329               0x064, BIT(0), 0);
0330 static SUNXI_CCU_GATE(bus_tcon0_clk,    "bus-tcon0",    "ahb1",
0331               0x064, BIT(4), 0);
0332 static SUNXI_CCU_GATE(bus_tcon1_clk,    "bus-tcon1",    "ahb1",
0333               0x064, BIT(5), 0);
0334 static SUNXI_CCU_GATE(bus_csi_clk,  "bus-csi",  "ahb1",
0335               0x064, BIT(8), 0);
0336 static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb1",
0337               0x064, BIT(11), 0);
0338 static SUNXI_CCU_GATE(bus_de_clk,   "bus-de",   "ahb1",
0339               0x064, BIT(12), 0);
0340 static SUNXI_CCU_GATE(bus_gpu_clk,  "bus-gpu",  "ahb1",
0341               0x064, BIT(20), 0);
0342 static SUNXI_CCU_GATE(bus_msgbox_clk,   "bus-msgbox",   "ahb1",
0343               0x064, BIT(21), 0);
0344 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
0345               0x064, BIT(22), 0);
0346 
0347 static SUNXI_CCU_GATE(bus_spdif_clk,    "bus-spdif",    "apb1",
0348               0x068, BIT(1), 0);
0349 static SUNXI_CCU_GATE(bus_pio_clk,  "bus-pio",  "apb1",
0350               0x068, BIT(5), 0);
0351 static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
0352               0x068, BIT(12), 0);
0353 static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
0354               0x068, BIT(13), 0);
0355 static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1",
0356               0x068, BIT(14), 0);
0357 static SUNXI_CCU_GATE(bus_tdm_clk,  "bus-tdm",  "apb1",
0358               0x068, BIT(15), 0);
0359 
0360 static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
0361               0x06c, BIT(0), 0);
0362 static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
0363               0x06c, BIT(1), 0);
0364 static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
0365               0x06c, BIT(2), 0);
0366 static SUNXI_CCU_GATE(bus_uart0_clk,    "bus-uart0",    "apb2",
0367               0x06c, BIT(16), 0);
0368 static SUNXI_CCU_GATE(bus_uart1_clk,    "bus-uart1",    "apb2",
0369               0x06c, BIT(17), 0);
0370 static SUNXI_CCU_GATE(bus_uart2_clk,    "bus-uart2",    "apb2",
0371               0x06c, BIT(18), 0);
0372 static SUNXI_CCU_GATE(bus_uart3_clk,    "bus-uart3",    "apb2",
0373               0x06c, BIT(19), 0);
0374 static SUNXI_CCU_GATE(bus_uart4_clk,    "bus-uart4",    "apb2",
0375               0x06c, BIT(20), 0);
0376 
0377 static const char * const cci400_parents[] = { "osc24M", "pll-periph",
0378                            "pll-hsic" };
0379 static struct ccu_div cci400_clk = {
0380     .div        = _SUNXI_CCU_DIV_FLAGS(0, 2, 0),
0381     .mux        = _SUNXI_CCU_MUX(24, 2),
0382     .common     = {
0383         .reg        = 0x078,
0384         .hw.init    = CLK_HW_INIT_PARENTS("cci400",
0385                               cci400_parents,
0386                               &ccu_div_ops,
0387                               CLK_IS_CRITICAL),
0388     },
0389 };
0390 
0391 static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
0392 
0393 static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents,
0394                   0x080,
0395                   0, 4,     /* M */
0396                   16, 2,    /* P */
0397                   24, 2,    /* mux */
0398                   BIT(31),  /* gate */
0399                   0);
0400 
0401 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
0402                   0x088,
0403                   0, 4,     /* M */
0404                   16, 2,    /* P */
0405                   24, 2,    /* mux */
0406                   BIT(31),  /* gate */
0407                   0);
0408 
0409 static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0-sample", "mmc0",
0410                0x088, 20, 3, 0);
0411 static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0-output", "mmc0",
0412                0x088, 8, 3, 0);
0413 
0414 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
0415                   0x08c,
0416                   0, 4,     /* M */
0417                   16, 2,    /* P */
0418                   24, 2,    /* mux */
0419                   BIT(31),  /* gate */
0420                   0);
0421 
0422 static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1",
0423                0x08c, 20, 3, 0);
0424 static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1",
0425                0x08c, 8, 3, 0);
0426 
0427 static SUNXI_CCU_MP_MMC_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
0428                       0x090, 0);
0429 
0430 static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2",
0431                0x090, 20, 3, 0);
0432 static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2-output", "mmc2",
0433                0x090, 8, 3, 0);
0434 
0435 static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents,
0436                   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,
0444                   0x0a0,
0445                   0, 4,     /* M */
0446                   16, 2,    /* P */
0447                   24, 4,    /* mux */
0448                   BIT(31),  /* gate */
0449                   0);
0450 
0451 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents,
0452                   0x0a4,
0453                   0, 4,     /* M */
0454                   16, 2,    /* P */
0455                   24, 4,    /* mux */
0456                   BIT(31),  /* gate */
0457                   0);
0458 
0459 static SUNXI_CCU_M_WITH_GATE(i2s0_clk, "i2s0", "pll-audio",
0460                  0x0b0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
0461 static SUNXI_CCU_M_WITH_GATE(i2s1_clk, "i2s1", "pll-audio",
0462                  0x0b4, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
0463 static SUNXI_CCU_M_WITH_GATE(i2s2_clk, "i2s2", "pll-audio",
0464                  0x0b8, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
0465 static SUNXI_CCU_M_WITH_GATE(tdm_clk, "tdm", "pll-audio",
0466                  0x0bc, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
0467 static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
0468                  0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
0469 
0470 static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
0471               0x0cc, BIT(8), 0);
0472 static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
0473               0x0cc, BIT(9), 0);
0474 static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic",
0475               0x0cc, BIT(10), 0);
0476 static struct ccu_gate usb_hsic_12m_clk = {
0477     .enable = BIT(11),
0478     .common = {
0479         .reg        = 0x0cc,
0480         .prediv     = 2,
0481         .features   = CCU_FEATURE_ALL_PREDIV,
0482         .hw.init    = CLK_HW_INIT("usb-hsic-12m", "osc24M",
0483                           &ccu_gate_ops, 0),
0484     }
0485 };
0486 static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "osc24M",
0487               0x0cc, BIT(16), 0);
0488 
0489 /* TODO divider has minimum of 2 */
0490 static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", 0x0f4, 0, 4, CLK_IS_CRITICAL);
0491 
0492 static SUNXI_CCU_GATE(dram_ve_clk,  "dram-ve",  "dram",
0493               0x100, BIT(0), 0);
0494 static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram",
0495               0x100, BIT(1), 0);
0496 
0497 static const char * const tcon0_parents[] = { "pll-video0" };
0498 static SUNXI_CCU_MUX_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
0499                  0x118, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
0500 
0501 static const char * const tcon1_parents[] = { "pll-video1" };
0502 static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_clk, "tcon1", tcon1_parents,
0503                  0x11c, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
0504 
0505 static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
0506 
0507 static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0);
0508 
0509 static const char * const csi_mclk_parents[] = { "pll-video0", "pll-de",
0510                          "osc24M" };
0511 static const u8 csi_mclk_table[] = { 0, 3, 5 };
0512 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
0513                        csi_mclk_parents, csi_mclk_table,
0514                        0x134,
0515                        0, 5,    /* M */
0516                        8, 3,    /* mux */
0517                        BIT(15), /* gate */
0518                        0);
0519 
0520 static const char * const csi_sclk_parents[] = { "pll-periph", "pll-ve" };
0521 static const u8 csi_sclk_table[] = { 0, 5 };
0522 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
0523                        csi_sclk_parents, csi_sclk_table,
0524                        0x134,
0525                        16, 4,   /* M */
0526                        24, 3,   /* mux */
0527                        BIT(31), /* gate */
0528                        0);
0529 
0530 static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c,
0531                  16, 3, BIT(31), CLK_SET_RATE_PARENT);
0532 
0533 static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0);
0534 
0535 static const char * const hdmi_parents[] = { "pll-video1" };
0536 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
0537                  0x150,
0538                  0, 4,  /* M */
0539                  24, 2, /* mux */
0540                  BIT(31),   /* gate */
0541                  CLK_SET_RATE_PARENT);
0542 
0543 static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0x154, BIT(31), 0);
0544 
0545 static const char * const mbus_parents[] = { "osc24M", "pll-periph",
0546                          "pll-ddr" };
0547 static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
0548                  0x15c,
0549                  0, 3,  /* M */
0550                  24, 2, /* mux */
0551                  BIT(31),   /* gate */
0552                  CLK_IS_CRITICAL);
0553 
0554 static const char * const mipi_dsi0_parents[] = { "pll-video0" };
0555 static const u8 mipi_dsi0_table[] = { 8 };
0556 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk, "mipi-dsi0",
0557                        mipi_dsi0_parents, mipi_dsi0_table,
0558                        0x168,
0559                        0, 4,    /* M */
0560                        24, 4,   /* mux */
0561                        BIT(31), /* gate */
0562                        CLK_SET_RATE_PARENT);
0563 
0564 static const char * const mipi_dsi1_parents[] = { "osc24M", "pll-video0" };
0565 static const u8 mipi_dsi1_table[] = { 0, 9 };
0566 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk, "mipi-dsi1",
0567                        mipi_dsi1_parents, mipi_dsi1_table,
0568                        0x16c,
0569                        0, 4,    /* M */
0570                        24, 4,   /* mux */
0571                        BIT(31), /* gate */
0572                        CLK_SET_RATE_PARENT);
0573 
0574 static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu", 0x1a0,
0575                  0, 3, BIT(31), CLK_SET_RATE_PARENT);
0576 
0577 static const char * const gpu_memory_parents[] = { "pll-gpu", "pll-ddr" };
0578 static SUNXI_CCU_M_WITH_MUX_GATE(gpu_memory_clk, "gpu-memory",
0579                  gpu_memory_parents,
0580                  0x1a4,
0581                  0, 3,      /* M */
0582                  24, 1,     /* mux */
0583                  BIT(31),   /* gate */
0584                  CLK_SET_RATE_PARENT);
0585 
0586 static SUNXI_CCU_M_WITH_GATE(gpu_hyd_clk, "gpu-hyd", "pll-gpu", 0x1a8,
0587                  0, 3, BIT(31), CLK_SET_RATE_PARENT);
0588 
0589 static struct ccu_common *sun8i_a83t_ccu_clks[] = {
0590     &pll_c0cpux_clk.common,
0591     &pll_c1cpux_clk.common,
0592     &pll_audio_clk.common,
0593     &pll_video0_clk.common,
0594     &pll_ve_clk.common,
0595     &pll_ddr_clk.common,
0596     &pll_periph_clk.common,
0597     &pll_gpu_clk.common,
0598     &pll_hsic_clk.common,
0599     &pll_de_clk.common,
0600     &pll_video1_clk.common,
0601     &c0cpux_clk.common,
0602     &c1cpux_clk.common,
0603     &axi0_clk.common,
0604     &axi1_clk.common,
0605     &ahb1_clk.common,
0606     &ahb2_clk.common,
0607     &apb1_clk.common,
0608     &apb2_clk.common,
0609     &bus_mipi_dsi_clk.common,
0610     &bus_ss_clk.common,
0611     &bus_dma_clk.common,
0612     &bus_mmc0_clk.common,
0613     &bus_mmc1_clk.common,
0614     &bus_mmc2_clk.common,
0615     &bus_nand_clk.common,
0616     &bus_dram_clk.common,
0617     &bus_emac_clk.common,
0618     &bus_hstimer_clk.common,
0619     &bus_spi0_clk.common,
0620     &bus_spi1_clk.common,
0621     &bus_otg_clk.common,
0622     &bus_ehci0_clk.common,
0623     &bus_ehci1_clk.common,
0624     &bus_ohci0_clk.common,
0625     &bus_ve_clk.common,
0626     &bus_tcon0_clk.common,
0627     &bus_tcon1_clk.common,
0628     &bus_csi_clk.common,
0629     &bus_hdmi_clk.common,
0630     &bus_de_clk.common,
0631     &bus_gpu_clk.common,
0632     &bus_msgbox_clk.common,
0633     &bus_spinlock_clk.common,
0634     &bus_spdif_clk.common,
0635     &bus_pio_clk.common,
0636     &bus_i2s0_clk.common,
0637     &bus_i2s1_clk.common,
0638     &bus_i2s2_clk.common,
0639     &bus_tdm_clk.common,
0640     &bus_i2c0_clk.common,
0641     &bus_i2c1_clk.common,
0642     &bus_i2c2_clk.common,
0643     &bus_uart0_clk.common,
0644     &bus_uart1_clk.common,
0645     &bus_uart2_clk.common,
0646     &bus_uart3_clk.common,
0647     &bus_uart4_clk.common,
0648     &cci400_clk.common,
0649     &nand_clk.common,
0650     &mmc0_clk.common,
0651     &mmc0_sample_clk.common,
0652     &mmc0_output_clk.common,
0653     &mmc1_clk.common,
0654     &mmc1_sample_clk.common,
0655     &mmc1_output_clk.common,
0656     &mmc2_clk.common,
0657     &mmc2_sample_clk.common,
0658     &mmc2_output_clk.common,
0659     &ss_clk.common,
0660     &spi0_clk.common,
0661     &spi1_clk.common,
0662     &i2s0_clk.common,
0663     &i2s1_clk.common,
0664     &i2s2_clk.common,
0665     &tdm_clk.common,
0666     &spdif_clk.common,
0667     &usb_phy0_clk.common,
0668     &usb_phy1_clk.common,
0669     &usb_hsic_clk.common,
0670     &usb_hsic_12m_clk.common,
0671     &usb_ohci0_clk.common,
0672     &dram_clk.common,
0673     &dram_ve_clk.common,
0674     &dram_csi_clk.common,
0675     &tcon0_clk.common,
0676     &tcon1_clk.common,
0677     &csi_misc_clk.common,
0678     &mipi_csi_clk.common,
0679     &csi_mclk_clk.common,
0680     &csi_sclk_clk.common,
0681     &ve_clk.common,
0682     &avs_clk.common,
0683     &hdmi_clk.common,
0684     &hdmi_slow_clk.common,
0685     &mbus_clk.common,
0686     &mipi_dsi0_clk.common,
0687     &mipi_dsi1_clk.common,
0688     &gpu_core_clk.common,
0689     &gpu_memory_clk.common,
0690     &gpu_hyd_clk.common,
0691 };
0692 
0693 static struct clk_hw_onecell_data sun8i_a83t_hw_clks = {
0694     .hws    = {
0695         [CLK_PLL_C0CPUX]    = &pll_c0cpux_clk.common.hw,
0696         [CLK_PLL_C1CPUX]    = &pll_c1cpux_clk.common.hw,
0697         [CLK_PLL_AUDIO]     = &pll_audio_clk.common.hw,
0698         [CLK_PLL_VIDEO0]    = &pll_video0_clk.common.hw,
0699         [CLK_PLL_VE]        = &pll_ve_clk.common.hw,
0700         [CLK_PLL_DDR]       = &pll_ddr_clk.common.hw,
0701         [CLK_PLL_PERIPH]    = &pll_periph_clk.common.hw,
0702         [CLK_PLL_GPU]       = &pll_gpu_clk.common.hw,
0703         [CLK_PLL_HSIC]      = &pll_hsic_clk.common.hw,
0704         [CLK_PLL_DE]        = &pll_de_clk.common.hw,
0705         [CLK_PLL_VIDEO1]    = &pll_video1_clk.common.hw,
0706         [CLK_C0CPUX]        = &c0cpux_clk.common.hw,
0707         [CLK_C1CPUX]        = &c1cpux_clk.common.hw,
0708         [CLK_AXI0]      = &axi0_clk.common.hw,
0709         [CLK_AXI1]      = &axi1_clk.common.hw,
0710         [CLK_AHB1]      = &ahb1_clk.common.hw,
0711         [CLK_AHB2]      = &ahb2_clk.common.hw,
0712         [CLK_APB1]      = &apb1_clk.common.hw,
0713         [CLK_APB2]      = &apb2_clk.common.hw,
0714         [CLK_BUS_MIPI_DSI]  = &bus_mipi_dsi_clk.common.hw,
0715         [CLK_BUS_SS]        = &bus_ss_clk.common.hw,
0716         [CLK_BUS_DMA]       = &bus_dma_clk.common.hw,
0717         [CLK_BUS_MMC0]      = &bus_mmc0_clk.common.hw,
0718         [CLK_BUS_MMC1]      = &bus_mmc1_clk.common.hw,
0719         [CLK_BUS_MMC2]      = &bus_mmc2_clk.common.hw,
0720         [CLK_BUS_NAND]      = &bus_nand_clk.common.hw,
0721         [CLK_BUS_DRAM]      = &bus_dram_clk.common.hw,
0722         [CLK_BUS_EMAC]      = &bus_emac_clk.common.hw,
0723         [CLK_BUS_HSTIMER]   = &bus_hstimer_clk.common.hw,
0724         [CLK_BUS_SPI0]      = &bus_spi0_clk.common.hw,
0725         [CLK_BUS_SPI1]      = &bus_spi1_clk.common.hw,
0726         [CLK_BUS_OTG]       = &bus_otg_clk.common.hw,
0727         [CLK_BUS_EHCI0]     = &bus_ehci0_clk.common.hw,
0728         [CLK_BUS_EHCI1]     = &bus_ehci1_clk.common.hw,
0729         [CLK_BUS_OHCI0]     = &bus_ohci0_clk.common.hw,
0730         [CLK_BUS_VE]        = &bus_ve_clk.common.hw,
0731         [CLK_BUS_TCON0]     = &bus_tcon0_clk.common.hw,
0732         [CLK_BUS_TCON1]     = &bus_tcon1_clk.common.hw,
0733         [CLK_BUS_CSI]       = &bus_csi_clk.common.hw,
0734         [CLK_BUS_HDMI]      = &bus_hdmi_clk.common.hw,
0735         [CLK_BUS_DE]        = &bus_de_clk.common.hw,
0736         [CLK_BUS_GPU]       = &bus_gpu_clk.common.hw,
0737         [CLK_BUS_MSGBOX]    = &bus_msgbox_clk.common.hw,
0738         [CLK_BUS_SPINLOCK]  = &bus_spinlock_clk.common.hw,
0739         [CLK_BUS_SPDIF]     = &bus_spdif_clk.common.hw,
0740         [CLK_BUS_PIO]       = &bus_pio_clk.common.hw,
0741         [CLK_BUS_I2S0]      = &bus_i2s0_clk.common.hw,
0742         [CLK_BUS_I2S1]      = &bus_i2s1_clk.common.hw,
0743         [CLK_BUS_I2S2]      = &bus_i2s2_clk.common.hw,
0744         [CLK_BUS_TDM]       = &bus_tdm_clk.common.hw,
0745         [CLK_BUS_I2C0]      = &bus_i2c0_clk.common.hw,
0746         [CLK_BUS_I2C1]      = &bus_i2c1_clk.common.hw,
0747         [CLK_BUS_I2C2]      = &bus_i2c2_clk.common.hw,
0748         [CLK_BUS_UART0]     = &bus_uart0_clk.common.hw,
0749         [CLK_BUS_UART1]     = &bus_uart1_clk.common.hw,
0750         [CLK_BUS_UART2]     = &bus_uart2_clk.common.hw,
0751         [CLK_BUS_UART3]     = &bus_uart3_clk.common.hw,
0752         [CLK_BUS_UART4]     = &bus_uart4_clk.common.hw,
0753         [CLK_CCI400]        = &cci400_clk.common.hw,
0754         [CLK_NAND]      = &nand_clk.common.hw,
0755         [CLK_MMC0]      = &mmc0_clk.common.hw,
0756         [CLK_MMC0_SAMPLE]   = &mmc0_sample_clk.common.hw,
0757         [CLK_MMC0_OUTPUT]   = &mmc0_output_clk.common.hw,
0758         [CLK_MMC1]      = &mmc1_clk.common.hw,
0759         [CLK_MMC1_SAMPLE]   = &mmc1_sample_clk.common.hw,
0760         [CLK_MMC1_OUTPUT]   = &mmc1_output_clk.common.hw,
0761         [CLK_MMC2]      = &mmc2_clk.common.hw,
0762         [CLK_MMC2_SAMPLE]   = &mmc2_sample_clk.common.hw,
0763         [CLK_MMC2_OUTPUT]   = &mmc2_output_clk.common.hw,
0764         [CLK_SS]        = &ss_clk.common.hw,
0765         [CLK_SPI0]      = &spi0_clk.common.hw,
0766         [CLK_SPI1]      = &spi1_clk.common.hw,
0767         [CLK_I2S0]      = &i2s0_clk.common.hw,
0768         [CLK_I2S1]      = &i2s1_clk.common.hw,
0769         [CLK_I2S2]      = &i2s2_clk.common.hw,
0770         [CLK_TDM]       = &tdm_clk.common.hw,
0771         [CLK_SPDIF]     = &spdif_clk.common.hw,
0772         [CLK_USB_PHY0]      = &usb_phy0_clk.common.hw,
0773         [CLK_USB_PHY1]      = &usb_phy1_clk.common.hw,
0774         [CLK_USB_HSIC]      = &usb_hsic_clk.common.hw,
0775         [CLK_USB_HSIC_12M]  = &usb_hsic_12m_clk.common.hw,
0776         [CLK_USB_OHCI0]     = &usb_ohci0_clk.common.hw,
0777         [CLK_DRAM]      = &dram_clk.common.hw,
0778         [CLK_DRAM_VE]       = &dram_ve_clk.common.hw,
0779         [CLK_DRAM_CSI]      = &dram_csi_clk.common.hw,
0780         [CLK_TCON0]     = &tcon0_clk.common.hw,
0781         [CLK_TCON1]     = &tcon1_clk.common.hw,
0782         [CLK_CSI_MISC]      = &csi_misc_clk.common.hw,
0783         [CLK_MIPI_CSI]      = &mipi_csi_clk.common.hw,
0784         [CLK_CSI_MCLK]      = &csi_mclk_clk.common.hw,
0785         [CLK_CSI_SCLK]      = &csi_sclk_clk.common.hw,
0786         [CLK_VE]        = &ve_clk.common.hw,
0787         [CLK_AVS]       = &avs_clk.common.hw,
0788         [CLK_HDMI]      = &hdmi_clk.common.hw,
0789         [CLK_HDMI_SLOW]     = &hdmi_slow_clk.common.hw,
0790         [CLK_MBUS]      = &mbus_clk.common.hw,
0791         [CLK_MIPI_DSI0]     = &mipi_dsi0_clk.common.hw,
0792         [CLK_MIPI_DSI1]     = &mipi_dsi1_clk.common.hw,
0793         [CLK_GPU_CORE]      = &gpu_core_clk.common.hw,
0794         [CLK_GPU_MEMORY]    = &gpu_memory_clk.common.hw,
0795         [CLK_GPU_HYD]       = &gpu_hyd_clk.common.hw,
0796     },
0797     .num    = CLK_NUMBER,
0798 };
0799 
0800 static struct ccu_reset_map sun8i_a83t_ccu_resets[] = {
0801     [RST_USB_PHY0]      = { 0x0cc, BIT(0) },
0802     [RST_USB_PHY1]      = { 0x0cc, BIT(1) },
0803     [RST_USB_HSIC]      = { 0x0cc, BIT(2) },
0804     [RST_DRAM]      = { 0x0f4, BIT(31) },
0805     [RST_MBUS]      = { 0x0fc, BIT(31) },
0806     [RST_BUS_MIPI_DSI]  = { 0x2c0, BIT(1) },
0807     [RST_BUS_SS]        = { 0x2c0, BIT(5) },
0808     [RST_BUS_DMA]       = { 0x2c0, BIT(6) },
0809     [RST_BUS_MMC0]      = { 0x2c0, BIT(8) },
0810     [RST_BUS_MMC1]      = { 0x2c0, BIT(9) },
0811     [RST_BUS_MMC2]      = { 0x2c0, BIT(10) },
0812     [RST_BUS_NAND]      = { 0x2c0, BIT(13) },
0813     [RST_BUS_DRAM]      = { 0x2c0, BIT(14) },
0814     [RST_BUS_EMAC]      = { 0x2c0, BIT(17) },
0815     [RST_BUS_HSTIMER]   = { 0x2c0, BIT(19) },
0816     [RST_BUS_SPI0]      = { 0x2c0, BIT(20) },
0817     [RST_BUS_SPI1]      = { 0x2c0, BIT(21) },
0818     [RST_BUS_OTG]       = { 0x2c0, BIT(24) },
0819     [RST_BUS_EHCI0]     = { 0x2c0, BIT(26) },
0820     [RST_BUS_EHCI1]     = { 0x2c0, BIT(27) },
0821     [RST_BUS_OHCI0]     = { 0x2c0, BIT(29) },
0822     [RST_BUS_VE]        = { 0x2c4, BIT(0) },
0823     [RST_BUS_TCON0]     = { 0x2c4, BIT(4) },
0824     [RST_BUS_TCON1]     = { 0x2c4, BIT(5) },
0825     [RST_BUS_CSI]       = { 0x2c4, BIT(8) },
0826     [RST_BUS_HDMI0]     = { 0x2c4, BIT(10) },
0827     [RST_BUS_HDMI1]     = { 0x2c4, BIT(11) },
0828     [RST_BUS_DE]        = { 0x2c4, BIT(12) },
0829     [RST_BUS_GPU]       = { 0x2c4, BIT(20) },
0830     [RST_BUS_MSGBOX]    = { 0x2c4, BIT(21) },
0831     [RST_BUS_SPINLOCK]  = { 0x2c4, BIT(22) },
0832     [RST_BUS_LVDS]      = { 0x2c8, BIT(0) },
0833     [RST_BUS_SPDIF]     = { 0x2d0, BIT(1) },
0834     [RST_BUS_I2S0]      = { 0x2d0, BIT(12) },
0835     [RST_BUS_I2S1]      = { 0x2d0, BIT(13) },
0836     [RST_BUS_I2S2]      = { 0x2d0, BIT(14) },
0837     [RST_BUS_TDM]       = { 0x2d0, BIT(15) },
0838     [RST_BUS_I2C0]      = { 0x2d8, BIT(0) },
0839     [RST_BUS_I2C1]      = { 0x2d8, BIT(1) },
0840     [RST_BUS_I2C2]      = { 0x2d8, BIT(2) },
0841     [RST_BUS_UART0]     = { 0x2d8, BIT(16) },
0842     [RST_BUS_UART1]     = { 0x2d8, BIT(17) },
0843     [RST_BUS_UART2]     = { 0x2d8, BIT(18) },
0844     [RST_BUS_UART3]     = { 0x2d8, BIT(19) },
0845     [RST_BUS_UART4]     = { 0x2d8, BIT(20) },
0846 };
0847 
0848 static const struct sunxi_ccu_desc sun8i_a83t_ccu_desc = {
0849     .ccu_clks   = sun8i_a83t_ccu_clks,
0850     .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_ccu_clks),
0851 
0852     .hw_clks    = &sun8i_a83t_hw_clks,
0853 
0854     .resets     = sun8i_a83t_ccu_resets,
0855     .num_resets = ARRAY_SIZE(sun8i_a83t_ccu_resets),
0856 };
0857 
0858 #define SUN8I_A83T_PLL_P_SHIFT  16
0859 #define SUN8I_A83T_PLL_N_SHIFT  8
0860 #define SUN8I_A83T_PLL_N_WIDTH  8
0861 
0862 static void sun8i_a83t_cpu_pll_fixup(void __iomem *reg)
0863 {
0864     u32 val = readl(reg);
0865 
0866     /* bail out if P divider is not used */
0867     if (!(val & BIT(SUN8I_A83T_PLL_P_SHIFT)))
0868         return;
0869 
0870     /*
0871      * If P is used, output should be less than 288 MHz. When we
0872      * set P to 1, we should also decrease the multiplier so the
0873      * output doesn't go out of range, but not too much such that
0874      * the multiplier stays above 12, the minimal operation value.
0875      *
0876      * To keep it simple, set the multiplier to 17, the reset value.
0877      */
0878     val &= ~GENMASK(SUN8I_A83T_PLL_N_SHIFT + SUN8I_A83T_PLL_N_WIDTH - 1,
0879             SUN8I_A83T_PLL_N_SHIFT);
0880     val |= 17 << SUN8I_A83T_PLL_N_SHIFT;
0881 
0882     /* And clear P */
0883     val &= ~BIT(SUN8I_A83T_PLL_P_SHIFT);
0884 
0885     writel(val, reg);
0886 }
0887 
0888 static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
0889 {
0890     void __iomem *reg;
0891     u32 val;
0892 
0893     reg = devm_platform_ioremap_resource(pdev, 0);
0894     if (IS_ERR(reg))
0895         return PTR_ERR(reg);
0896 
0897     /* Enforce d1 = 0, d2 = 1 for Audio PLL */
0898     val = readl(reg + SUN8I_A83T_PLL_AUDIO_REG);
0899     val &= ~BIT(16);
0900     val |= BIT(18);
0901     writel(val, reg + SUN8I_A83T_PLL_AUDIO_REG);
0902 
0903     /* Enforce P = 1 for both CPU cluster PLLs */
0904     sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG);
0905     sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG);
0906 
0907     return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a83t_ccu_desc);
0908 }
0909 
0910 static const struct of_device_id sun8i_a83t_ccu_ids[] = {
0911     { .compatible = "allwinner,sun8i-a83t-ccu" },
0912     { }
0913 };
0914 
0915 static struct platform_driver sun8i_a83t_ccu_driver = {
0916     .probe  = sun8i_a83t_ccu_probe,
0917     .driver = {
0918         .name   = "sun8i-a83t-ccu",
0919         .suppress_bind_attrs = true,
0920         .of_match_table = sun8i_a83t_ccu_ids,
0921     },
0922 };
0923 module_platform_driver(sun8i_a83t_ccu_driver);
0924 
0925 MODULE_IMPORT_NS(SUNXI_CCU);
0926 MODULE_LICENSE("GPL");