root/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sun8i_a83t_cpu_pll_fixup
  2. sun8i_a83t_ccu_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
   4  */
   5 
   6 #include <linux/clk-provider.h>
   7 #include <linux/io.h>
   8 #include <linux/of_address.h>
   9 #include <linux/platform_device.h>
  10 
  11 #include "ccu_common.h"
  12 #include "ccu_reset.h"
  13 
  14 #include "ccu_div.h"
  15 #include "ccu_gate.h"
  16 #include "ccu_mp.h"
  17 #include "ccu_mux.h"
  18 #include "ccu_nkmp.h"
  19 #include "ccu_nm.h"
  20 #include "ccu_phase.h"
  21 
  22 #include "ccu-sun8i-a83t.h"
  23 
  24 #define CCU_SUN8I_A83T_LOCK_REG 0x20c
  25 
  26 /*
  27  * The CPU PLLs are actually NP clocks, with P being /1 or /4. However
  28  * P should only be used for output frequencies lower than 228 MHz.
  29  * Neither mainline Linux, U-boot, nor the vendor BSPs use these.
  30  *
  31  * For now we can just model it as a multiplier clock, and force P to /1.
  32  */
  33 #define SUN8I_A83T_PLL_C0CPUX_REG       0x000
  34 #define SUN8I_A83T_PLL_C1CPUX_REG       0x004
  35 
  36 static struct ccu_mult pll_c0cpux_clk = {
  37         .enable         = BIT(31),
  38         .lock           = BIT(0),
  39         .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
  40         .common         = {
  41                 .reg            = SUN8I_A83T_PLL_C0CPUX_REG,
  42                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
  43                 .features       = CCU_FEATURE_LOCK_REG,
  44                 .hw.init        = CLK_HW_INIT("pll-c0cpux", "osc24M",
  45                                               &ccu_mult_ops,
  46                                               CLK_SET_RATE_UNGATE),
  47         },
  48 };
  49 
  50 static struct ccu_mult pll_c1cpux_clk = {
  51         .enable         = BIT(31),
  52         .lock           = BIT(1),
  53         .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
  54         .common         = {
  55                 .reg            = SUN8I_A83T_PLL_C1CPUX_REG,
  56                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
  57                 .features       = CCU_FEATURE_LOCK_REG,
  58                 .hw.init        = CLK_HW_INIT("pll-c1cpux", "osc24M",
  59                                               &ccu_mult_ops,
  60                                               CLK_SET_RATE_UNGATE),
  61         },
  62 };
  63 
  64 /*
  65  * The Audio PLL has d1, d2 dividers in addition to the usual N, M
  66  * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
  67  * and 24.576 MHz, ignore them for now. Enforce the default for them,
  68  * which is d1 = 0, d2 = 1.
  69  */
  70 #define SUN8I_A83T_PLL_AUDIO_REG        0x008
  71 
  72 /* clock rates doubled for post divider */
  73 static struct ccu_sdm_setting pll_audio_sdm_table[] = {
  74         { .rate = 45158400, .pattern = 0xc00121ff, .m = 29, .n = 54 },
  75         { .rate = 49152000, .pattern = 0xc000e147, .m = 30, .n = 61 },
  76 };
  77 
  78 static struct ccu_nm pll_audio_clk = {
  79         .enable         = BIT(31),
  80         .lock           = BIT(2),
  81         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
  82         .m              = _SUNXI_CCU_DIV(0, 6),
  83         .fixed_post_div = 2,
  84         .sdm            = _SUNXI_CCU_SDM(pll_audio_sdm_table, BIT(24),
  85                                          0x284, BIT(31)),
  86         .common         = {
  87                 .reg            = SUN8I_A83T_PLL_AUDIO_REG,
  88                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
  89                 .features       = CCU_FEATURE_LOCK_REG |
  90                                   CCU_FEATURE_FIXED_POSTDIV |
  91                                   CCU_FEATURE_SIGMA_DELTA_MOD,
  92                 .hw.init        = CLK_HW_INIT("pll-audio", "osc24M",
  93                                               &ccu_nm_ops, CLK_SET_RATE_UNGATE),
  94         },
  95 };
  96 
  97 /* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
  98 static struct ccu_nkmp pll_video0_clk = {
  99         .enable         = BIT(31),
 100         .lock           = BIT(3),
 101         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 102         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 103         .p              = _SUNXI_CCU_DIV(0, 2), /* output divider */
 104         .max_rate       = 3000000000UL,
 105         .common         = {
 106                 .reg            = 0x010,
 107                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 108                 .features       = CCU_FEATURE_LOCK_REG,
 109                 .hw.init        = CLK_HW_INIT("pll-video0", "osc24M",
 110                                               &ccu_nkmp_ops,
 111                                               CLK_SET_RATE_UNGATE),
 112         },
 113 };
 114 
 115 static struct ccu_nkmp pll_ve_clk = {
 116         .enable         = BIT(31),
 117         .lock           = BIT(4),
 118         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 119         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 120         .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
 121         .common         = {
 122                 .reg            = 0x018,
 123                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 124                 .features       = CCU_FEATURE_LOCK_REG,
 125                 .hw.init        = CLK_HW_INIT("pll-ve", "osc24M",
 126                                               &ccu_nkmp_ops,
 127                                               CLK_SET_RATE_UNGATE),
 128         },
 129 };
 130 
 131 static struct ccu_nkmp pll_ddr_clk = {
 132         .enable         = BIT(31),
 133         .lock           = BIT(5),
 134         .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
 135         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 136         .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
 137         .common         = {
 138                 .reg            = 0x020,
 139                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 140                 .features       = CCU_FEATURE_LOCK_REG,
 141                 .hw.init        = CLK_HW_INIT("pll-ddr", "osc24M",
 142                                               &ccu_nkmp_ops,
 143                                               CLK_SET_RATE_UNGATE),
 144         },
 145 };
 146 
 147 static struct ccu_nkmp pll_periph_clk = {
 148         .enable         = BIT(31),
 149         .lock           = BIT(6),
 150         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 151         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 152         .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
 153         .common         = {
 154                 .reg            = 0x028,
 155                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 156                 .features       = CCU_FEATURE_LOCK_REG,
 157                 .hw.init        = CLK_HW_INIT("pll-periph", "osc24M",
 158                                               &ccu_nkmp_ops,
 159                                               CLK_SET_RATE_UNGATE),
 160         },
 161 };
 162 
 163 static struct ccu_nkmp pll_gpu_clk = {
 164         .enable         = BIT(31),
 165         .lock           = BIT(7),
 166         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 167         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 168         .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
 169         .common         = {
 170                 .reg            = 0x038,
 171                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 172                 .features       = CCU_FEATURE_LOCK_REG,
 173                 .hw.init        = CLK_HW_INIT("pll-gpu", "osc24M",
 174                                               &ccu_nkmp_ops,
 175                                               CLK_SET_RATE_UNGATE),
 176         },
 177 };
 178 
 179 static struct ccu_nkmp pll_hsic_clk = {
 180         .enable         = BIT(31),
 181         .lock           = BIT(8),
 182         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 183         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 184         .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
 185         .common         = {
 186                 .reg            = 0x044,
 187                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 188                 .features       = CCU_FEATURE_LOCK_REG,
 189                 .hw.init        = CLK_HW_INIT("pll-hsic", "osc24M",
 190                                               &ccu_nkmp_ops,
 191                                               CLK_SET_RATE_UNGATE),
 192         },
 193 };
 194 
 195 static struct ccu_nkmp pll_de_clk = {
 196         .enable         = BIT(31),
 197         .lock           = BIT(9),
 198         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 199         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 200         .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
 201         .common         = {
 202                 .reg            = 0x048,
 203                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 204                 .features       = CCU_FEATURE_LOCK_REG,
 205                 .hw.init        = CLK_HW_INIT("pll-de", "osc24M",
 206                                               &ccu_nkmp_ops,
 207                                               CLK_SET_RATE_UNGATE),
 208         },
 209 };
 210 
 211 static struct ccu_nkmp pll_video1_clk = {
 212         .enable         = BIT(31),
 213         .lock           = BIT(10),
 214         .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
 215         .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
 216         .p              = _SUNXI_CCU_DIV(0, 2), /* external divider p */
 217         .max_rate       = 3000000000UL,
 218         .common         = {
 219                 .reg            = 0x04c,
 220                 .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
 221                 .features       = CCU_FEATURE_LOCK_REG,
 222                 .hw.init        = CLK_HW_INIT("pll-video1", "osc24M",
 223                                               &ccu_nkmp_ops,
 224                                               CLK_SET_RATE_UNGATE),
 225         },
 226 };
 227 
 228 static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" };
 229 static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents,
 230                      0x50, 12, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
 231 
 232 static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" };
 233 static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents,
 234                      0x50, 28, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
 235 
 236 static SUNXI_CCU_M(axi0_clk, "axi0", "c0cpux", 0x050, 0, 2, 0);
 237 static SUNXI_CCU_M(axi1_clk, "axi1", "c1cpux", 0x050, 16, 2, 0);
 238 
 239 static const char * const ahb1_parents[] = { "osc16M-d512", "osc24M",
 240                                              "pll-periph",
 241                                              "pll-periph" };
 242 static const struct ccu_mux_var_prediv ahb1_predivs[] = {
 243         { .index = 2, .shift = 6, .width = 2 },
 244         { .index = 3, .shift = 6, .width = 2 },
 245 };
 246 static struct ccu_div ahb1_clk = {
 247         .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 248         .mux            = {
 249                 .shift  = 12,
 250                 .width  = 2,
 251 
 252                 .var_predivs    = ahb1_predivs,
 253                 .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
 254         },
 255         .common         = {
 256                 .reg            = 0x054,
 257                 .hw.init        = CLK_HW_INIT_PARENTS("ahb1",
 258                                                       ahb1_parents,
 259                                                       &ccu_div_ops,
 260                                                       0),
 261         },
 262 };
 263 
 264 static SUNXI_CCU_M(apb1_clk, "apb1", "ahb1", 0x054, 8, 2, 0);
 265 
 266 static const char * const apb2_parents[] = { "osc16M-d512", "osc24M",
 267                                              "pll-periph", "pll-periph" };
 268 
 269 static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
 270                              0, 5,      /* M */
 271                              16, 2,     /* P */
 272                              24, 2,     /* mux */
 273                              0);
 274 
 275 static const char * const ahb2_parents[] = { "ahb1", "pll-periph" };
 276 static const struct ccu_mux_fixed_prediv ahb2_prediv = {
 277         .index = 1, .div = 2
 278 };
 279 static struct ccu_mux ahb2_clk = {
 280         .mux            = {
 281                 .shift          = 0,
 282                 .width          = 2,
 283                 .fixed_predivs  = &ahb2_prediv,
 284                 .n_predivs      = 1,
 285         },
 286         .common         = {
 287                 .reg            = 0x05c,
 288                 .hw.init        = CLK_HW_INIT_PARENTS("ahb2",
 289                                                       ahb2_parents,
 290                                                       &ccu_mux_ops,
 291                                                       0),
 292         },
 293 };
 294 
 295 static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
 296                       0x060, BIT(1), 0);
 297 static SUNXI_CCU_GATE(bus_ss_clk,       "bus-ss",       "ahb1",
 298                       0x060, BIT(5), 0);
 299 static SUNXI_CCU_GATE(bus_dma_clk,      "bus-dma",      "ahb1",
 300                       0x060, BIT(6), 0);
 301 static SUNXI_CCU_GATE(bus_mmc0_clk,     "bus-mmc0",     "ahb1",
 302                       0x060, BIT(8), 0);
 303 static SUNXI_CCU_GATE(bus_mmc1_clk,     "bus-mmc1",     "ahb1",
 304                       0x060, BIT(9), 0);
 305 static SUNXI_CCU_GATE(bus_mmc2_clk,     "bus-mmc2",     "ahb1",
 306                       0x060, BIT(10), 0);
 307 static SUNXI_CCU_GATE(bus_nand_clk,     "bus-nand",     "ahb1",
 308                       0x060, BIT(13), 0);
 309 static SUNXI_CCU_GATE(bus_dram_clk,     "bus-dram",     "ahb1",
 310                       0x060, BIT(14), 0);
 311 static SUNXI_CCU_GATE(bus_emac_clk,     "bus-emac",     "ahb2",
 312                       0x060, BIT(17), 0);
 313 static SUNXI_CCU_GATE(bus_hstimer_clk,  "bus-hstimer",  "ahb1",
 314                       0x060, BIT(19), 0);
 315 static SUNXI_CCU_GATE(bus_spi0_clk,     "bus-spi0",     "ahb1",
 316                       0x060, BIT(20), 0);
 317 static SUNXI_CCU_GATE(bus_spi1_clk,     "bus-spi1",     "ahb1",
 318                       0x060, BIT(21), 0);
 319 static SUNXI_CCU_GATE(bus_otg_clk,      "bus-otg",      "ahb1",
 320                       0x060, BIT(24), 0);
 321 static SUNXI_CCU_GATE(bus_ehci0_clk,    "bus-ehci0",    "ahb2",
 322                       0x060, BIT(26), 0);
 323 static SUNXI_CCU_GATE(bus_ehci1_clk,    "bus-ehci1",    "ahb2",
 324                       0x060, BIT(27), 0);
 325 static SUNXI_CCU_GATE(bus_ohci0_clk,    "bus-ohci0",    "ahb2",
 326                       0x060, BIT(29), 0);
 327 
 328 static SUNXI_CCU_GATE(bus_ve_clk,       "bus-ve",       "ahb1",
 329                       0x064, BIT(0), 0);
 330 static SUNXI_CCU_GATE(bus_tcon0_clk,    "bus-tcon0",    "ahb1",
 331                       0x064, BIT(4), 0);
 332 static SUNXI_CCU_GATE(bus_tcon1_clk,    "bus-tcon1",    "ahb1",
 333                       0x064, BIT(5), 0);
 334 static SUNXI_CCU_GATE(bus_csi_clk,      "bus-csi",      "ahb1",
 335                       0x064, BIT(8), 0);
 336 static SUNXI_CCU_GATE(bus_hdmi_clk,     "bus-hdmi",     "ahb1",
 337                       0x064, BIT(11), 0);
 338 static SUNXI_CCU_GATE(bus_de_clk,       "bus-de",       "ahb1",
 339                       0x064, BIT(12), 0);
 340 static SUNXI_CCU_GATE(bus_gpu_clk,      "bus-gpu",      "ahb1",
 341                       0x064, BIT(20), 0);
 342 static SUNXI_CCU_GATE(bus_msgbox_clk,   "bus-msgbox",   "ahb1",
 343                       0x064, BIT(21), 0);
 344 static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
 345                       0x064, BIT(22), 0);
 346 
 347 static SUNXI_CCU_GATE(bus_spdif_clk,    "bus-spdif",    "apb1",
 348                       0x068, BIT(1), 0);
 349 static SUNXI_CCU_GATE(bus_pio_clk,      "bus-pio",      "apb1",
 350                       0x068, BIT(5), 0);
 351 static SUNXI_CCU_GATE(bus_i2s0_clk,     "bus-i2s0",     "apb1",
 352                       0x068, BIT(12), 0);
 353 static SUNXI_CCU_GATE(bus_i2s1_clk,     "bus-i2s1",     "apb1",
 354                       0x068, BIT(13), 0);
 355 static SUNXI_CCU_GATE(bus_i2s2_clk,     "bus-i2s2",     "apb1",
 356                       0x068, BIT(14), 0);
 357 static SUNXI_CCU_GATE(bus_tdm_clk,      "bus-tdm",      "apb1",
 358                       0x068, BIT(15), 0);
 359 
 360 static SUNXI_CCU_GATE(bus_i2c0_clk,     "bus-i2c0",     "apb2",
 361                       0x06c, BIT(0), 0);
 362 static SUNXI_CCU_GATE(bus_i2c1_clk,     "bus-i2c1",     "apb2",
 363                       0x06c, BIT(1), 0);
 364 static SUNXI_CCU_GATE(bus_i2c2_clk,     "bus-i2c2",     "apb2",
 365                       0x06c, BIT(2), 0);
 366 static SUNXI_CCU_GATE(bus_uart0_clk,    "bus-uart0",    "apb2",
 367                       0x06c, BIT(16), 0);
 368 static SUNXI_CCU_GATE(bus_uart1_clk,    "bus-uart1",    "apb2",
 369                       0x06c, BIT(17), 0);
 370 static SUNXI_CCU_GATE(bus_uart2_clk,    "bus-uart2",    "apb2",
 371                       0x06c, BIT(18), 0);
 372 static SUNXI_CCU_GATE(bus_uart3_clk,    "bus-uart3",    "apb2",
 373                       0x06c, BIT(19), 0);
 374 static SUNXI_CCU_GATE(bus_uart4_clk,    "bus-uart4",    "apb2",
 375                       0x06c, BIT(20), 0);
 376 
 377 static const char * const cci400_parents[] = { "osc24M", "pll-periph",
 378                                                "pll-hsic" };
 379 static struct ccu_div cci400_clk = {
 380         .div            = _SUNXI_CCU_DIV_FLAGS(0, 2, 0),
 381         .mux            = _SUNXI_CCU_MUX(24, 2),
 382         .common         = {
 383                 .reg            = 0x078,
 384                 .hw.init        = CLK_HW_INIT_PARENTS("cci400",
 385                                                       cci400_parents,
 386                                                       &ccu_div_ops,
 387                                                       CLK_IS_CRITICAL),
 388         },
 389 };
 390 
 391 static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
 392 
 393 static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents,
 394                                   0x080,
 395                                   0, 4,         /* M */
 396                                   16, 2,        /* P */
 397                                   24, 2,        /* mux */
 398                                   BIT(31),      /* gate */
 399                                   0);
 400 
 401 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
 402                                   0x088,
 403                                   0, 4,         /* M */
 404                                   16, 2,        /* P */
 405                                   24, 2,        /* mux */
 406                                   BIT(31),      /* gate */
 407                                   0);
 408 
 409 static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0-sample", "mmc0",
 410                        0x088, 20, 3, 0);
 411 static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0-output", "mmc0",
 412                        0x088, 8, 3, 0);
 413 
 414 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
 415                                   0x08c,
 416                                   0, 4,         /* M */
 417                                   16, 2,        /* P */
 418                                   24, 2,        /* mux */
 419                                   BIT(31),      /* gate */
 420                                   0);
 421 
 422 static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1",
 423                        0x08c, 20, 3, 0);
 424 static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1",
 425                        0x08c, 8, 3, 0);
 426 
 427 static SUNXI_CCU_MP_MMC_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
 428                                       0x090, 0);
 429 
 430 static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2",
 431                        0x090, 20, 3, 0);
 432 static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2-output", "mmc2",
 433                        0x090, 8, 3, 0);
 434 
 435 static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents,
 436                                   0x09c,
 437                                   0, 4,         /* M */
 438                                   16, 2,        /* P */
 439                                   24, 2,        /* mux */
 440                                   BIT(31),      /* gate */
 441                                   0);
 442 
 443 static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents,
 444                                   0x0a0,
 445                                   0, 4,         /* M */
 446                                   16, 2,        /* P */
 447                                   24, 4,        /* mux */
 448                                   BIT(31),      /* gate */
 449                                   0);
 450 
 451 static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents,
 452                                   0x0a4,
 453                                   0, 4,         /* M */
 454                                   16, 2,        /* P */
 455                                   24, 4,        /* mux */
 456                                   BIT(31),      /* gate */
 457                                   0);
 458 
 459 static SUNXI_CCU_M_WITH_GATE(i2s0_clk, "i2s0", "pll-audio",
 460                              0x0b0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
 461 static SUNXI_CCU_M_WITH_GATE(i2s1_clk, "i2s1", "pll-audio",
 462                              0x0b4, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
 463 static SUNXI_CCU_M_WITH_GATE(i2s2_clk, "i2s2", "pll-audio",
 464                              0x0b8, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
 465 static SUNXI_CCU_M_WITH_GATE(tdm_clk, "tdm", "pll-audio",
 466                              0x0bc, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
 467 static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
 468                              0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
 469 
 470 static SUNXI_CCU_GATE(usb_phy0_clk,     "usb-phy0",     "osc24M",
 471                       0x0cc, BIT(8), 0);
 472 static SUNXI_CCU_GATE(usb_phy1_clk,     "usb-phy1",     "osc24M",
 473                       0x0cc, BIT(9), 0);
 474 static SUNXI_CCU_GATE(usb_hsic_clk,     "usb-hsic",     "pll-hsic",
 475                       0x0cc, BIT(10), 0);
 476 static struct ccu_gate usb_hsic_12m_clk = {
 477         .enable = BIT(11),
 478         .common = {
 479                 .reg            = 0x0cc,
 480                 .prediv         = 2,
 481                 .features       = CCU_FEATURE_ALL_PREDIV,
 482                 .hw.init        = CLK_HW_INIT("usb-hsic-12m", "osc24M",
 483                                               &ccu_gate_ops, 0),
 484         }
 485 };
 486 static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "osc24M",
 487                       0x0cc, BIT(16), 0);
 488 
 489 /* TODO divider has minimum of 2 */
 490 static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", 0x0f4, 0, 4, CLK_IS_CRITICAL);
 491 
 492 static SUNXI_CCU_GATE(dram_ve_clk,      "dram-ve",      "dram",
 493                       0x100, BIT(0), 0);
 494 static SUNXI_CCU_GATE(dram_csi_clk,     "dram-csi",     "dram",
 495                       0x100, BIT(1), 0);
 496 
 497 static const char * const tcon0_parents[] = { "pll-video0" };
 498 static SUNXI_CCU_MUX_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
 499                                  0x118, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
 500 
 501 static const char * const tcon1_parents[] = { "pll-video1" };
 502 static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_clk, "tcon1", tcon1_parents,
 503                                  0x11c, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
 504 
 505 static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
 506 
 507 static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0);
 508 
 509 static const char * const csi_mclk_parents[] = { "pll-video0", "pll-de",
 510                                                  "osc24M" };
 511 static const u8 csi_mclk_table[] = { 0, 3, 5 };
 512 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
 513                                        csi_mclk_parents, csi_mclk_table,
 514                                        0x134,
 515                                        0, 5,    /* M */
 516                                        8, 3,    /* mux */
 517                                        BIT(15), /* gate */
 518                                        0);
 519 
 520 static const char * const csi_sclk_parents[] = { "pll-periph", "pll-ve" };
 521 static const u8 csi_sclk_table[] = { 0, 5 };
 522 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
 523                                        csi_sclk_parents, csi_sclk_table,
 524                                        0x134,
 525                                        16, 4,   /* M */
 526                                        24, 3,   /* mux */
 527                                        BIT(31), /* gate */
 528                                        0);
 529 
 530 static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c,
 531                              16, 3, BIT(31), CLK_SET_RATE_PARENT);
 532 
 533 static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0);
 534 
 535 static const char * const hdmi_parents[] = { "pll-video1" };
 536 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
 537                                  0x150,
 538                                  0, 4,  /* M */
 539                                  24, 2, /* mux */
 540                                  BIT(31),       /* gate */
 541                                  CLK_SET_RATE_PARENT);
 542 
 543 static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0x154, BIT(31), 0);
 544 
 545 static const char * const mbus_parents[] = { "osc24M", "pll-periph",
 546                                              "pll-ddr" };
 547 static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
 548                                  0x15c,
 549                                  0, 3,  /* M */
 550                                  24, 2, /* mux */
 551                                  BIT(31),       /* gate */
 552                                  CLK_IS_CRITICAL);
 553 
 554 static const char * const mipi_dsi0_parents[] = { "pll-video0" };
 555 static const u8 mipi_dsi0_table[] = { 8 };
 556 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk, "mipi-dsi0",
 557                                        mipi_dsi0_parents, mipi_dsi0_table,
 558                                        0x168,
 559                                        0, 4,    /* M */
 560                                        24, 4,   /* mux */
 561                                        BIT(31), /* gate */
 562                                        CLK_SET_RATE_PARENT);
 563 
 564 static const char * const mipi_dsi1_parents[] = { "osc24M", "pll-video0" };
 565 static const u8 mipi_dsi1_table[] = { 0, 9 };
 566 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk, "mipi-dsi1",
 567                                        mipi_dsi1_parents, mipi_dsi1_table,
 568                                        0x16c,
 569                                        0, 4,    /* M */
 570                                        24, 4,   /* mux */
 571                                        BIT(31), /* gate */
 572                                        CLK_SET_RATE_PARENT);
 573 
 574 static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu", 0x1a0,
 575                              0, 3, BIT(31), CLK_SET_RATE_PARENT);
 576 
 577 static const char * const gpu_memory_parents[] = { "pll-gpu", "pll-ddr" };
 578 static SUNXI_CCU_M_WITH_MUX_GATE(gpu_memory_clk, "gpu-memory",
 579                                  gpu_memory_parents,
 580                                  0x1a4,
 581                                  0, 3,          /* M */
 582                                  24, 1,         /* mux */
 583                                  BIT(31),       /* gate */
 584                                  CLK_SET_RATE_PARENT);
 585 
 586 static SUNXI_CCU_M_WITH_GATE(gpu_hyd_clk, "gpu-hyd", "pll-gpu", 0x1a8,
 587                              0, 3, BIT(31), CLK_SET_RATE_PARENT);
 588 
 589 static struct ccu_common *sun8i_a83t_ccu_clks[] = {
 590         &pll_c0cpux_clk.common,
 591         &pll_c1cpux_clk.common,
 592         &pll_audio_clk.common,
 593         &pll_video0_clk.common,
 594         &pll_ve_clk.common,
 595         &pll_ddr_clk.common,
 596         &pll_periph_clk.common,
 597         &pll_gpu_clk.common,
 598         &pll_hsic_clk.common,
 599         &pll_de_clk.common,
 600         &pll_video1_clk.common,
 601         &c0cpux_clk.common,
 602         &c1cpux_clk.common,
 603         &axi0_clk.common,
 604         &axi1_clk.common,
 605         &ahb1_clk.common,
 606         &ahb2_clk.common,
 607         &apb1_clk.common,
 608         &apb2_clk.common,
 609         &bus_mipi_dsi_clk.common,
 610         &bus_ss_clk.common,
 611         &bus_dma_clk.common,
 612         &bus_mmc0_clk.common,
 613         &bus_mmc1_clk.common,
 614         &bus_mmc2_clk.common,
 615         &bus_nand_clk.common,
 616         &bus_dram_clk.common,
 617         &bus_emac_clk.common,
 618         &bus_hstimer_clk.common,
 619         &bus_spi0_clk.common,
 620         &bus_spi1_clk.common,
 621         &bus_otg_clk.common,
 622         &bus_ehci0_clk.common,
 623         &bus_ehci1_clk.common,
 624         &bus_ohci0_clk.common,
 625         &bus_ve_clk.common,
 626         &bus_tcon0_clk.common,
 627         &bus_tcon1_clk.common,
 628         &bus_csi_clk.common,
 629         &bus_hdmi_clk.common,
 630         &bus_de_clk.common,
 631         &bus_gpu_clk.common,
 632         &bus_msgbox_clk.common,
 633         &bus_spinlock_clk.common,
 634         &bus_spdif_clk.common,
 635         &bus_pio_clk.common,
 636         &bus_i2s0_clk.common,
 637         &bus_i2s1_clk.common,
 638         &bus_i2s2_clk.common,
 639         &bus_tdm_clk.common,
 640         &bus_i2c0_clk.common,
 641         &bus_i2c1_clk.common,
 642         &bus_i2c2_clk.common,
 643         &bus_uart0_clk.common,
 644         &bus_uart1_clk.common,
 645         &bus_uart2_clk.common,
 646         &bus_uart3_clk.common,
 647         &bus_uart4_clk.common,
 648         &cci400_clk.common,
 649         &nand_clk.common,
 650         &mmc0_clk.common,
 651         &mmc0_sample_clk.common,
 652         &mmc0_output_clk.common,
 653         &mmc1_clk.common,
 654         &mmc1_sample_clk.common,
 655         &mmc1_output_clk.common,
 656         &mmc2_clk.common,
 657         &mmc2_sample_clk.common,
 658         &mmc2_output_clk.common,
 659         &ss_clk.common,
 660         &spi0_clk.common,
 661         &spi1_clk.common,
 662         &i2s0_clk.common,
 663         &i2s1_clk.common,
 664         &i2s2_clk.common,
 665         &tdm_clk.common,
 666         &spdif_clk.common,
 667         &usb_phy0_clk.common,
 668         &usb_phy1_clk.common,
 669         &usb_hsic_clk.common,
 670         &usb_hsic_12m_clk.common,
 671         &usb_ohci0_clk.common,
 672         &dram_clk.common,
 673         &dram_ve_clk.common,
 674         &dram_csi_clk.common,
 675         &tcon0_clk.common,
 676         &tcon1_clk.common,
 677         &csi_misc_clk.common,
 678         &mipi_csi_clk.common,
 679         &csi_mclk_clk.common,
 680         &csi_sclk_clk.common,
 681         &ve_clk.common,
 682         &avs_clk.common,
 683         &hdmi_clk.common,
 684         &hdmi_slow_clk.common,
 685         &mbus_clk.common,
 686         &mipi_dsi0_clk.common,
 687         &mipi_dsi1_clk.common,
 688         &gpu_core_clk.common,
 689         &gpu_memory_clk.common,
 690         &gpu_hyd_clk.common,
 691 };
 692 
 693 static struct clk_hw_onecell_data sun8i_a83t_hw_clks = {
 694         .hws    = {
 695                 [CLK_PLL_C0CPUX]        = &pll_c0cpux_clk.common.hw,
 696                 [CLK_PLL_C1CPUX]        = &pll_c1cpux_clk.common.hw,
 697                 [CLK_PLL_AUDIO]         = &pll_audio_clk.common.hw,
 698                 [CLK_PLL_VIDEO0]        = &pll_video0_clk.common.hw,
 699                 [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
 700                 [CLK_PLL_DDR]           = &pll_ddr_clk.common.hw,
 701                 [CLK_PLL_PERIPH]        = &pll_periph_clk.common.hw,
 702                 [CLK_PLL_GPU]           = &pll_gpu_clk.common.hw,
 703                 [CLK_PLL_HSIC]          = &pll_hsic_clk.common.hw,
 704                 [CLK_PLL_DE]            = &pll_de_clk.common.hw,
 705                 [CLK_PLL_VIDEO1]        = &pll_video1_clk.common.hw,
 706                 [CLK_C0CPUX]            = &c0cpux_clk.common.hw,
 707                 [CLK_C1CPUX]            = &c1cpux_clk.common.hw,
 708                 [CLK_AXI0]              = &axi0_clk.common.hw,
 709                 [CLK_AXI1]              = &axi1_clk.common.hw,
 710                 [CLK_AHB1]              = &ahb1_clk.common.hw,
 711                 [CLK_AHB2]              = &ahb2_clk.common.hw,
 712                 [CLK_APB1]              = &apb1_clk.common.hw,
 713                 [CLK_APB2]              = &apb2_clk.common.hw,
 714                 [CLK_BUS_MIPI_DSI]      = &bus_mipi_dsi_clk.common.hw,
 715                 [CLK_BUS_SS]            = &bus_ss_clk.common.hw,
 716                 [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
 717                 [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
 718                 [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
 719                 [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
 720                 [CLK_BUS_NAND]          = &bus_nand_clk.common.hw,
 721                 [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
 722                 [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
 723                 [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
 724                 [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
 725                 [CLK_BUS_SPI1]          = &bus_spi1_clk.common.hw,
 726                 [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
 727                 [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
 728                 [CLK_BUS_EHCI1]         = &bus_ehci1_clk.common.hw,
 729                 [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
 730                 [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
 731                 [CLK_BUS_TCON0]         = &bus_tcon0_clk.common.hw,
 732                 [CLK_BUS_TCON1]         = &bus_tcon1_clk.common.hw,
 733                 [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
 734                 [CLK_BUS_HDMI]          = &bus_hdmi_clk.common.hw,
 735                 [CLK_BUS_DE]            = &bus_de_clk.common.hw,
 736                 [CLK_BUS_GPU]           = &bus_gpu_clk.common.hw,
 737                 [CLK_BUS_MSGBOX]        = &bus_msgbox_clk.common.hw,
 738                 [CLK_BUS_SPINLOCK]      = &bus_spinlock_clk.common.hw,
 739                 [CLK_BUS_SPDIF]         = &bus_spdif_clk.common.hw,
 740                 [CLK_BUS_PIO]           = &bus_pio_clk.common.hw,
 741                 [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
 742                 [CLK_BUS_I2S1]          = &bus_i2s1_clk.common.hw,
 743                 [CLK_BUS_I2S2]          = &bus_i2s2_clk.common.hw,
 744                 [CLK_BUS_TDM]           = &bus_tdm_clk.common.hw,
 745                 [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
 746                 [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
 747                 [CLK_BUS_I2C2]          = &bus_i2c2_clk.common.hw,
 748                 [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
 749                 [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
 750                 [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
 751                 [CLK_BUS_UART3]         = &bus_uart3_clk.common.hw,
 752                 [CLK_BUS_UART4]         = &bus_uart4_clk.common.hw,
 753                 [CLK_CCI400]            = &cci400_clk.common.hw,
 754                 [CLK_NAND]              = &nand_clk.common.hw,
 755                 [CLK_MMC0]              = &mmc0_clk.common.hw,
 756                 [CLK_MMC0_SAMPLE]       = &mmc0_sample_clk.common.hw,
 757                 [CLK_MMC0_OUTPUT]       = &mmc0_output_clk.common.hw,
 758                 [CLK_MMC1]              = &mmc1_clk.common.hw,
 759                 [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
 760                 [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
 761                 [CLK_MMC2]              = &mmc2_clk.common.hw,
 762                 [CLK_MMC2_SAMPLE]       = &mmc2_sample_clk.common.hw,
 763                 [CLK_MMC2_OUTPUT]       = &mmc2_output_clk.common.hw,
 764                 [CLK_SS]                = &ss_clk.common.hw,
 765                 [CLK_SPI0]              = &spi0_clk.common.hw,
 766                 [CLK_SPI1]              = &spi1_clk.common.hw,
 767                 [CLK_I2S0]              = &i2s0_clk.common.hw,
 768                 [CLK_I2S1]              = &i2s1_clk.common.hw,
 769                 [CLK_I2S2]              = &i2s2_clk.common.hw,
 770                 [CLK_TDM]               = &tdm_clk.common.hw,
 771                 [CLK_SPDIF]             = &spdif_clk.common.hw,
 772                 [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
 773                 [CLK_USB_PHY1]          = &usb_phy1_clk.common.hw,
 774                 [CLK_USB_HSIC]          = &usb_hsic_clk.common.hw,
 775                 [CLK_USB_HSIC_12M]      = &usb_hsic_12m_clk.common.hw,
 776                 [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
 777                 [CLK_DRAM]              = &dram_clk.common.hw,
 778                 [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
 779                 [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
 780                 [CLK_TCON0]             = &tcon0_clk.common.hw,
 781                 [CLK_TCON1]             = &tcon1_clk.common.hw,
 782                 [CLK_CSI_MISC]          = &csi_misc_clk.common.hw,
 783                 [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
 784                 [CLK_CSI_MCLK]          = &csi_mclk_clk.common.hw,
 785                 [CLK_CSI_SCLK]          = &csi_sclk_clk.common.hw,
 786                 [CLK_VE]                = &ve_clk.common.hw,
 787                 [CLK_AVS]               = &avs_clk.common.hw,
 788                 [CLK_HDMI]              = &hdmi_clk.common.hw,
 789                 [CLK_HDMI_SLOW]         = &hdmi_slow_clk.common.hw,
 790                 [CLK_MBUS]              = &mbus_clk.common.hw,
 791                 [CLK_MIPI_DSI0]         = &mipi_dsi0_clk.common.hw,
 792                 [CLK_MIPI_DSI1]         = &mipi_dsi1_clk.common.hw,
 793                 [CLK_GPU_CORE]          = &gpu_core_clk.common.hw,
 794                 [CLK_GPU_MEMORY]        = &gpu_memory_clk.common.hw,
 795                 [CLK_GPU_HYD]           = &gpu_hyd_clk.common.hw,
 796         },
 797         .num    = CLK_NUMBER,
 798 };
 799 
 800 static struct ccu_reset_map sun8i_a83t_ccu_resets[] = {
 801         [RST_USB_PHY0]          = { 0x0cc, BIT(0) },
 802         [RST_USB_PHY1]          = { 0x0cc, BIT(1) },
 803         [RST_USB_HSIC]          = { 0x0cc, BIT(2) },
 804         [RST_DRAM]              = { 0x0f4, BIT(31) },
 805         [RST_MBUS]              = { 0x0fc, BIT(31) },
 806         [RST_BUS_MIPI_DSI]      = { 0x2c0, BIT(1) },
 807         [RST_BUS_SS]            = { 0x2c0, BIT(5) },
 808         [RST_BUS_DMA]           = { 0x2c0, BIT(6) },
 809         [RST_BUS_MMC0]          = { 0x2c0, BIT(8) },
 810         [RST_BUS_MMC1]          = { 0x2c0, BIT(9) },
 811         [RST_BUS_MMC2]          = { 0x2c0, BIT(10) },
 812         [RST_BUS_NAND]          = { 0x2c0, BIT(13) },
 813         [RST_BUS_DRAM]          = { 0x2c0, BIT(14) },
 814         [RST_BUS_EMAC]          = { 0x2c0, BIT(17) },
 815         [RST_BUS_HSTIMER]       = { 0x2c0, BIT(19) },
 816         [RST_BUS_SPI0]          = { 0x2c0, BIT(20) },
 817         [RST_BUS_SPI1]          = { 0x2c0, BIT(21) },
 818         [RST_BUS_OTG]           = { 0x2c0, BIT(24) },
 819         [RST_BUS_EHCI0]         = { 0x2c0, BIT(26) },
 820         [RST_BUS_EHCI1]         = { 0x2c0, BIT(27) },
 821         [RST_BUS_OHCI0]         = { 0x2c0, BIT(29) },
 822         [RST_BUS_VE]            = { 0x2c4, BIT(0) },
 823         [RST_BUS_TCON0]         = { 0x2c4, BIT(4) },
 824         [RST_BUS_TCON1]         = { 0x2c4, BIT(5) },
 825         [RST_BUS_CSI]           = { 0x2c4, BIT(8) },
 826         [RST_BUS_HDMI0]         = { 0x2c4, BIT(10) },
 827         [RST_BUS_HDMI1]         = { 0x2c4, BIT(11) },
 828         [RST_BUS_DE]            = { 0x2c4, BIT(12) },
 829         [RST_BUS_GPU]           = { 0x2c4, BIT(20) },
 830         [RST_BUS_MSGBOX]        = { 0x2c4, BIT(21) },
 831         [RST_BUS_SPINLOCK]      = { 0x2c4, BIT(22) },
 832         [RST_BUS_LVDS]          = { 0x2c8, BIT(0) },
 833         [RST_BUS_SPDIF]         = { 0x2d0, BIT(1) },
 834         [RST_BUS_I2S0]          = { 0x2d0, BIT(12) },
 835         [RST_BUS_I2S1]          = { 0x2d0, BIT(13) },
 836         [RST_BUS_I2S2]          = { 0x2d0, BIT(14) },
 837         [RST_BUS_TDM]           = { 0x2d0, BIT(15) },
 838         [RST_BUS_I2C0]          = { 0x2d8, BIT(0) },
 839         [RST_BUS_I2C1]          = { 0x2d8, BIT(1) },
 840         [RST_BUS_I2C2]          = { 0x2d8, BIT(2) },
 841         [RST_BUS_UART0]         = { 0x2d8, BIT(16) },
 842         [RST_BUS_UART1]         = { 0x2d8, BIT(17) },
 843         [RST_BUS_UART2]         = { 0x2d8, BIT(18) },
 844         [RST_BUS_UART3]         = { 0x2d8, BIT(19) },
 845         [RST_BUS_UART4]         = { 0x2d8, BIT(20) },
 846 };
 847 
 848 static const struct sunxi_ccu_desc sun8i_a83t_ccu_desc = {
 849         .ccu_clks       = sun8i_a83t_ccu_clks,
 850         .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_ccu_clks),
 851 
 852         .hw_clks        = &sun8i_a83t_hw_clks,
 853 
 854         .resets         = sun8i_a83t_ccu_resets,
 855         .num_resets     = ARRAY_SIZE(sun8i_a83t_ccu_resets),
 856 };
 857 
 858 #define SUN8I_A83T_PLL_P_SHIFT  16
 859 #define SUN8I_A83T_PLL_N_SHIFT  8
 860 #define SUN8I_A83T_PLL_N_WIDTH  8
 861 
 862 static void sun8i_a83t_cpu_pll_fixup(void __iomem *reg)
 863 {
 864         u32 val = readl(reg);
 865 
 866         /* bail out if P divider is not used */
 867         if (!(val & BIT(SUN8I_A83T_PLL_P_SHIFT)))
 868                 return;
 869 
 870         /*
 871          * If P is used, output should be less than 288 MHz. When we
 872          * set P to 1, we should also decrease the multiplier so the
 873          * output doesn't go out of range, but not too much such that
 874          * the multiplier stays above 12, the minimal operation value.
 875          *
 876          * To keep it simple, set the multiplier to 17, the reset value.
 877          */
 878         val &= ~GENMASK(SUN8I_A83T_PLL_N_SHIFT + SUN8I_A83T_PLL_N_WIDTH - 1,
 879                         SUN8I_A83T_PLL_N_SHIFT);
 880         val |= 17 << SUN8I_A83T_PLL_N_SHIFT;
 881 
 882         /* And clear P */
 883         val &= ~BIT(SUN8I_A83T_PLL_P_SHIFT);
 884 
 885         writel(val, reg);
 886 }
 887 
 888 static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
 889 {
 890         struct resource *res;
 891         void __iomem *reg;
 892         u32 val;
 893 
 894         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 895         reg = devm_ioremap_resource(&pdev->dev, res);
 896         if (IS_ERR(reg))
 897                 return PTR_ERR(reg);
 898 
 899         /* Enforce d1 = 0, d2 = 1 for Audio PLL */
 900         val = readl(reg + SUN8I_A83T_PLL_AUDIO_REG);
 901         val &= ~BIT(16);
 902         val |= BIT(18);
 903         writel(val, reg + SUN8I_A83T_PLL_AUDIO_REG);
 904 
 905         /* Enforce P = 1 for both CPU cluster PLLs */
 906         sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG);
 907         sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG);
 908 
 909         return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc);
 910 }
 911 
 912 static const struct of_device_id sun8i_a83t_ccu_ids[] = {
 913         { .compatible = "allwinner,sun8i-a83t-ccu" },
 914         { }
 915 };
 916 
 917 static struct platform_driver sun8i_a83t_ccu_driver = {
 918         .probe  = sun8i_a83t_ccu_probe,
 919         .driver = {
 920                 .name   = "sun8i-a83t-ccu",
 921                 .of_match_table = sun8i_a83t_ccu_ids,
 922         },
 923 };
 924 builtin_platform_driver(sun8i_a83t_ccu_driver);

/* [<][>][^][v][top][bottom][index][help] */