linux/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
   3 *
   4 * Based on ccu-sun8i-h3.c, which is:
   5 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
   6 *
   7 * This software is licensed under the terms of the GNU General Public
   8 * License version 2, as published by the Free Software Foundation, and
   9 * may be copied, distributed, and modified under those terms.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#include <linux/clk-provider.h>
  18#include <linux/of_address.h>
  19
  20#include "ccu_common.h"
  21#include "ccu_reset.h"
  22
  23#include "ccu_div.h"
  24#include "ccu_gate.h"
  25#include "ccu_mp.h"
  26#include "ccu_mult.h"
  27#include "ccu_nk.h"
  28#include "ccu_nkm.h"
  29#include "ccu_nkmp.h"
  30#include "ccu_nm.h"
  31#include "ccu_phase.h"
  32
  33#include "ccu-sun8i-v3s.h"
  34
  35static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
  36                                     "osc24M", 0x000,
  37                                     8, 5,      /* N */
  38                                     4, 2,      /* K */
  39                                     0, 2,      /* M */
  40                                     16, 2,     /* P */
  41                                     BIT(31),   /* gate */
  42                                     BIT(28),   /* lock */
  43                                     0);
  44
  45/*
  46 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
  47 * the base (2x, 4x and 8x), and one variable divider (the one true
  48 * pll audio).
  49 *
  50 * We don't have any need for the variable divider for now, so we just
  51 * hardcode it to match with the clock names
  52 */
  53#define SUN8I_V3S_PLL_AUDIO_REG 0x008
  54
  55static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
  56                                   "osc24M", 0x008,
  57                                   8, 7,        /* N */
  58                                   0, 5,        /* M */
  59                                   BIT(31),     /* gate */
  60                                   BIT(28),     /* lock */
  61                                   0);
  62
  63static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
  64                                        "osc24M", 0x0010,
  65                                        8, 7,           /* N */
  66                                        0, 4,           /* M */
  67                                        BIT(24),        /* frac enable */
  68                                        BIT(25),        /* frac select */
  69                                        270000000,      /* frac rate 0 */
  70                                        297000000,      /* frac rate 1 */
  71                                        BIT(31),        /* gate */
  72                                        BIT(28),        /* lock */
  73                                        0);
  74
  75static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
  76                                        "osc24M", 0x0018,
  77                                        8, 7,           /* N */
  78                                        0, 4,           /* M */
  79                                        BIT(24),        /* frac enable */
  80                                        BIT(25),        /* frac select */
  81                                        270000000,      /* frac rate 0 */
  82                                        297000000,      /* frac rate 1 */
  83                                        BIT(31),        /* gate */
  84                                        BIT(28),        /* lock */
  85                                        0);
  86
  87static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
  88                                    "osc24M", 0x020,
  89                                    8, 5,       /* N */
  90                                    4, 2,       /* K */
  91                                    0, 2,       /* M */
  92                                    BIT(31),    /* gate */
  93                                    BIT(28),    /* lock */
  94                                    0);
  95
  96static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
  97                                           "osc24M", 0x028,
  98                                           8, 5,        /* N */
  99                                           4, 2,        /* K */
 100                                           BIT(31),     /* gate */
 101                                           BIT(28),     /* lock */
 102                                           2,           /* post-div */
 103                                           0);
 104
 105static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_isp_clk, "pll-isp",
 106                                        "osc24M", 0x002c,
 107                                        8, 7,           /* N */
 108                                        0, 4,           /* M */
 109                                        BIT(24),        /* frac enable */
 110                                        BIT(25),        /* frac select */
 111                                        270000000,      /* frac rate 0 */
 112                                        297000000,      /* frac rate 1 */
 113                                        BIT(31),        /* gate */
 114                                        BIT(28),        /* lock */
 115                                        0);
 116
 117static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
 118                                           "osc24M", 0x044,
 119                                           8, 5,        /* N */
 120                                           4, 2,        /* K */
 121                                           BIT(31),     /* gate */
 122                                           BIT(28),     /* lock */
 123                                           2,           /* post-div */
 124                                           0);
 125
 126static const char * const cpu_parents[] = { "osc32k", "osc24M",
 127                                             "pll-cpu", "pll-cpu" };
 128static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
 129                     0x050, 16, 2, CLK_IS_CRITICAL);
 130
 131static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
 132
 133static const char * const ahb1_parents[] = { "osc32k", "osc24M",
 134                                             "axi", "pll-periph0" };
 135static const struct ccu_mux_var_prediv ahb1_predivs[] = {
 136        { .index = 3, .shift = 6, .width = 2 },
 137};
 138static struct ccu_div ahb1_clk = {
 139        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 140
 141        .mux            = {
 142                .shift  = 12,
 143                .width  = 2,
 144
 145                .var_predivs    = ahb1_predivs,
 146                .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
 147        },
 148
 149        .common         = {
 150                .reg            = 0x054,
 151                .features       = CCU_FEATURE_VARIABLE_PREDIV,
 152                .hw.init        = CLK_HW_INIT_PARENTS("ahb1",
 153                                                      ahb1_parents,
 154                                                      &ccu_div_ops,
 155                                                      0),
 156        },
 157};
 158
 159static struct clk_div_table apb1_div_table[] = {
 160        { .val = 0, .div = 2 },
 161        { .val = 1, .div = 2 },
 162        { .val = 2, .div = 4 },
 163        { .val = 3, .div = 8 },
 164        { /* Sentinel */ },
 165};
 166static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
 167                           0x054, 8, 2, apb1_div_table, 0);
 168
 169static const char * const apb2_parents[] = { "osc32k", "osc24M",
 170                                             "pll-periph0", "pll-periph0" };
 171static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
 172                             0, 5,      /* M */
 173                             16, 2,     /* P */
 174                             24, 2,     /* mux */
 175                             0);
 176
 177static const char * const ahb2_parents[] = { "ahb1", "pll-periph0" };
 178static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
 179        { .index = 1, .div = 2 },
 180};
 181static struct ccu_mux ahb2_clk = {
 182        .mux            = {
 183                .shift  = 0,
 184                .width  = 1,
 185                .fixed_predivs  = ahb2_fixed_predivs,
 186                .n_predivs      = ARRAY_SIZE(ahb2_fixed_predivs),
 187        },
 188
 189        .common         = {
 190                .reg            = 0x05c,
 191                .features       = CCU_FEATURE_FIXED_PREDIV,
 192                .hw.init        = CLK_HW_INIT_PARENTS("ahb2",
 193                                                      ahb2_parents,
 194                                                      &ccu_mux_ops,
 195                                                      0),
 196        },
 197};
 198
 199static SUNXI_CCU_GATE(bus_ce_clk,       "bus-ce",       "ahb1",
 200                      0x060, BIT(5), 0);
 201static SUNXI_CCU_GATE(bus_dma_clk,      "bus-dma",      "ahb1",
 202                      0x060, BIT(6), 0);
 203static SUNXI_CCU_GATE(bus_mmc0_clk,     "bus-mmc0",     "ahb1",
 204                      0x060, BIT(8), 0);
 205static SUNXI_CCU_GATE(bus_mmc1_clk,     "bus-mmc1",     "ahb1",
 206                      0x060, BIT(9), 0);
 207static SUNXI_CCU_GATE(bus_mmc2_clk,     "bus-mmc2",     "ahb1",
 208                      0x060, BIT(10), 0);
 209static SUNXI_CCU_GATE(bus_dram_clk,     "bus-dram",     "ahb1",
 210                      0x060, BIT(14), 0);
 211static SUNXI_CCU_GATE(bus_emac_clk,     "bus-emac",     "ahb2",
 212                      0x060, BIT(17), 0);
 213static SUNXI_CCU_GATE(bus_hstimer_clk,  "bus-hstimer",  "ahb1",
 214                      0x060, BIT(19), 0);
 215static SUNXI_CCU_GATE(bus_spi0_clk,     "bus-spi0",     "ahb1",
 216                      0x060, BIT(20), 0);
 217static SUNXI_CCU_GATE(bus_otg_clk,      "bus-otg",      "ahb1",
 218                      0x060, BIT(24), 0);
 219static SUNXI_CCU_GATE(bus_ehci0_clk,    "bus-ehci0",    "ahb1",
 220                      0x060, BIT(26), 0);
 221static SUNXI_CCU_GATE(bus_ohci0_clk,    "bus-ohci0",    "ahb1",
 222                      0x060, BIT(29), 0);
 223
 224static SUNXI_CCU_GATE(bus_ve_clk,       "bus-ve",       "ahb1",
 225                      0x064, BIT(0), 0);
 226static SUNXI_CCU_GATE(bus_tcon0_clk,    "bus-tcon0",    "ahb1",
 227                      0x064, BIT(4), 0);
 228static SUNXI_CCU_GATE(bus_csi_clk,      "bus-csi",      "ahb1",
 229                      0x064, BIT(8), 0);
 230static SUNXI_CCU_GATE(bus_de_clk,       "bus-de",       "ahb1",
 231                      0x064, BIT(12), 0);
 232
 233static SUNXI_CCU_GATE(bus_codec_clk,    "bus-codec",    "apb1",
 234                      0x068, BIT(0), 0);
 235static SUNXI_CCU_GATE(bus_pio_clk,      "bus-pio",      "apb1",
 236                      0x068, BIT(5), 0);
 237
 238static SUNXI_CCU_GATE(bus_i2c0_clk,     "bus-i2c0",     "apb2",
 239                      0x06c, BIT(0), 0);
 240static SUNXI_CCU_GATE(bus_i2c1_clk,     "bus-i2c1",     "apb2",
 241                      0x06c, BIT(1), 0);
 242static SUNXI_CCU_GATE(bus_uart0_clk,    "bus-uart0",    "apb2",
 243                      0x06c, BIT(16), 0);
 244static SUNXI_CCU_GATE(bus_uart1_clk,    "bus-uart1",    "apb2",
 245                      0x06c, BIT(17), 0);
 246static SUNXI_CCU_GATE(bus_uart2_clk,    "bus-uart2",    "apb2",
 247                      0x06c, BIT(18), 0);
 248
 249static SUNXI_CCU_GATE(bus_ephy_clk,     "bus-ephy",     "ahb1",
 250                      0x070, BIT(0), 0);
 251static SUNXI_CCU_GATE(bus_dbg_clk,      "bus-dbg",      "ahb1",
 252                      0x070, BIT(7), 0);
 253
 254static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
 255                                                     "pll-periph1" };
 256static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
 257                                  0, 4,         /* M */
 258                                  16, 2,        /* P */
 259                                  24, 2,        /* mux */
 260                                  BIT(31),      /* gate */
 261                                  0);
 262
 263static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
 264                       0x088, 20, 3, 0);
 265static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
 266                       0x088, 8, 3, 0);
 267
 268static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
 269                                  0, 4,         /* M */
 270                                  16, 2,        /* P */
 271                                  24, 2,        /* mux */
 272                                  BIT(31),      /* gate */
 273                                  0);
 274
 275static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
 276                       0x08c, 20, 3, 0);
 277static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
 278                       0x08c, 8, 3, 0);
 279
 280static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
 281                                  0, 4,         /* M */
 282                                  16, 2,        /* P */
 283                                  24, 2,        /* mux */
 284                                  BIT(31),      /* gate */
 285                                  0);
 286
 287static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
 288                       0x090, 20, 3, 0);
 289static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
 290                       0x090, 8, 3, 0);
 291
 292static const char * const ce_parents[] = { "osc24M", "pll-periph0", };
 293
 294static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c,
 295                                  0, 4,         /* M */
 296                                  16, 2,        /* P */
 297                                  24, 2,        /* mux */
 298                                  BIT(31),      /* gate */
 299                                  0);
 300
 301static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
 302                                  0, 4,         /* M */
 303                                  16, 2,        /* P */
 304                                  24, 2,        /* mux */
 305                                  BIT(31),      /* gate */
 306                                  0);
 307
 308static SUNXI_CCU_GATE(usb_phy0_clk,     "usb-phy0",     "osc24M",
 309                      0x0cc, BIT(8), 0);
 310static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "osc24M",
 311                      0x0cc, BIT(16), 0);
 312
 313static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" };
 314static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
 315                            0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
 316
 317static SUNXI_CCU_GATE(dram_ve_clk,      "dram-ve",      "dram",
 318                      0x100, BIT(0), 0);
 319static SUNXI_CCU_GATE(dram_csi_clk,     "dram-csi",     "dram",
 320                      0x100, BIT(1), 0);
 321static SUNXI_CCU_GATE(dram_ehci_clk,    "dram-ehci",    "dram",
 322                      0x100, BIT(17), 0);
 323static SUNXI_CCU_GATE(dram_ohci_clk,    "dram-ohci",    "dram",
 324                      0x100, BIT(18), 0);
 325
 326static const char * const de_parents[] = { "pll-video", "pll-periph0" };
 327static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
 328                                 0x104, 0, 4, 24, 2, BIT(31), 0);
 329
 330static const char * const tcon_parents[] = { "pll-video" };
 331static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
 332                                 0x118, 0, 4, 24, 3, BIT(31), 0);
 333
 334static SUNXI_CCU_GATE(csi_misc_clk,     "csi-misc",     "osc24M",
 335                      0x130, BIT(31), 0);
 336
 337static const char * const csi_mclk_parents[] = { "osc24M", "pll-video",
 338                                                 "pll-periph0", "pll-periph1" };
 339static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
 340                                 0x130, 0, 5, 8, 3, BIT(15), 0);
 341
 342static const char * const csi1_sclk_parents[] = { "pll-video", "pll-isp" };
 343static SUNXI_CCU_M_WITH_MUX_GATE(csi1_sclk_clk, "csi-sclk", csi1_sclk_parents,
 344                                 0x134, 16, 4, 24, 3, BIT(31), 0);
 345
 346static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi-mclk", csi_mclk_parents,
 347                                 0x134, 0, 5, 8, 3, BIT(15), 0);
 348
 349static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
 350                             0x13c, 16, 3, BIT(31), 0);
 351
 352static SUNXI_CCU_GATE(ac_dig_clk,       "ac-dig",       "pll-audio",
 353                      0x140, BIT(31), CLK_SET_RATE_PARENT);
 354static SUNXI_CCU_GATE(avs_clk,          "avs",          "osc24M",
 355                      0x144, BIT(31), 0);
 356
 357static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x",
 358                                             "pll-ddr" };
 359static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
 360                                 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
 361
 362static const char * const mipi_csi_parents[] = { "pll-video", "pll-periph0",
 363                                                 "pll-isp" };
 364static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_clk, "mipi-csi", mipi_csi_parents,
 365                             0x16c, 0, 3, 24, 2, BIT(31), 0);
 366
 367static struct ccu_common *sun8i_v3s_ccu_clks[] = {
 368        &pll_cpu_clk.common,
 369        &pll_audio_base_clk.common,
 370        &pll_video_clk.common,
 371        &pll_ve_clk.common,
 372        &pll_ddr_clk.common,
 373        &pll_periph0_clk.common,
 374        &pll_isp_clk.common,
 375        &pll_periph1_clk.common,
 376        &cpu_clk.common,
 377        &axi_clk.common,
 378        &ahb1_clk.common,
 379        &apb1_clk.common,
 380        &apb2_clk.common,
 381        &ahb2_clk.common,
 382        &bus_ce_clk.common,
 383        &bus_dma_clk.common,
 384        &bus_mmc0_clk.common,
 385        &bus_mmc1_clk.common,
 386        &bus_mmc2_clk.common,
 387        &bus_dram_clk.common,
 388        &bus_emac_clk.common,
 389        &bus_hstimer_clk.common,
 390        &bus_spi0_clk.common,
 391        &bus_otg_clk.common,
 392        &bus_ehci0_clk.common,
 393        &bus_ohci0_clk.common,
 394        &bus_ve_clk.common,
 395        &bus_tcon0_clk.common,
 396        &bus_csi_clk.common,
 397        &bus_de_clk.common,
 398        &bus_codec_clk.common,
 399        &bus_pio_clk.common,
 400        &bus_i2c0_clk.common,
 401        &bus_i2c1_clk.common,
 402        &bus_uart0_clk.common,
 403        &bus_uart1_clk.common,
 404        &bus_uart2_clk.common,
 405        &bus_ephy_clk.common,
 406        &bus_dbg_clk.common,
 407        &mmc0_clk.common,
 408        &mmc0_sample_clk.common,
 409        &mmc0_output_clk.common,
 410        &mmc1_clk.common,
 411        &mmc1_sample_clk.common,
 412        &mmc1_output_clk.common,
 413        &mmc2_clk.common,
 414        &mmc2_sample_clk.common,
 415        &mmc2_output_clk.common,
 416        &ce_clk.common,
 417        &spi0_clk.common,
 418        &usb_phy0_clk.common,
 419        &usb_ohci0_clk.common,
 420        &dram_clk.common,
 421        &dram_ve_clk.common,
 422        &dram_csi_clk.common,
 423        &dram_ohci_clk.common,
 424        &dram_ehci_clk.common,
 425        &de_clk.common,
 426        &tcon_clk.common,
 427        &csi_misc_clk.common,
 428        &csi0_mclk_clk.common,
 429        &csi1_sclk_clk.common,
 430        &csi1_mclk_clk.common,
 431        &ve_clk.common,
 432        &ac_dig_clk.common,
 433        &avs_clk.common,
 434        &mbus_clk.common,
 435        &mipi_csi_clk.common,
 436};
 437
 438/* We hardcode the divider to 4 for now */
 439static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
 440                        "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
 441static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
 442                        "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
 443static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
 444                        "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
 445static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
 446                        "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
 447static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
 448                        "pll-periph0", 1, 2, 0);
 449
 450static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
 451        .hws    = {
 452                [CLK_PLL_CPU]           = &pll_cpu_clk.common.hw,
 453                [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
 454                [CLK_PLL_AUDIO]         = &pll_audio_clk.hw,
 455                [CLK_PLL_AUDIO_2X]      = &pll_audio_2x_clk.hw,
 456                [CLK_PLL_AUDIO_4X]      = &pll_audio_4x_clk.hw,
 457                [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
 458                [CLK_PLL_VIDEO]         = &pll_video_clk.common.hw,
 459                [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
 460                [CLK_PLL_DDR]           = &pll_ddr_clk.common.hw,
 461                [CLK_PLL_PERIPH0]       = &pll_periph0_clk.common.hw,
 462                [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
 463                [CLK_PLL_ISP]           = &pll_isp_clk.common.hw,
 464                [CLK_PLL_PERIPH1]       = &pll_periph1_clk.common.hw,
 465                [CLK_CPU]               = &cpu_clk.common.hw,
 466                [CLK_AXI]               = &axi_clk.common.hw,
 467                [CLK_AHB1]              = &ahb1_clk.common.hw,
 468                [CLK_APB1]              = &apb1_clk.common.hw,
 469                [CLK_APB2]              = &apb2_clk.common.hw,
 470                [CLK_AHB2]              = &ahb2_clk.common.hw,
 471                [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
 472                [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
 473                [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
 474                [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
 475                [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
 476                [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
 477                [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
 478                [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
 479                [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
 480                [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
 481                [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
 482                [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
 483                [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
 484                [CLK_BUS_TCON0]         = &bus_tcon0_clk.common.hw,
 485                [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
 486                [CLK_BUS_DE]            = &bus_de_clk.common.hw,
 487                [CLK_BUS_CODEC]         = &bus_codec_clk.common.hw,
 488                [CLK_BUS_PIO]           = &bus_pio_clk.common.hw,
 489                [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
 490                [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
 491                [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
 492                [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
 493                [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
 494                [CLK_BUS_EPHY]          = &bus_ephy_clk.common.hw,
 495                [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
 496                [CLK_MMC0]              = &mmc0_clk.common.hw,
 497                [CLK_MMC0_SAMPLE]       = &mmc0_sample_clk.common.hw,
 498                [CLK_MMC0_OUTPUT]       = &mmc0_output_clk.common.hw,
 499                [CLK_MMC1]              = &mmc1_clk.common.hw,
 500                [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
 501                [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
 502                [CLK_CE]                = &ce_clk.common.hw,
 503                [CLK_SPI0]              = &spi0_clk.common.hw,
 504                [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
 505                [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
 506                [CLK_DRAM]              = &dram_clk.common.hw,
 507                [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
 508                [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
 509                [CLK_DRAM_EHCI]         = &dram_ehci_clk.common.hw,
 510                [CLK_DRAM_OHCI]         = &dram_ohci_clk.common.hw,
 511                [CLK_DE]                = &de_clk.common.hw,
 512                [CLK_TCON0]             = &tcon_clk.common.hw,
 513                [CLK_CSI_MISC]          = &csi_misc_clk.common.hw,
 514                [CLK_CSI0_MCLK]         = &csi0_mclk_clk.common.hw,
 515                [CLK_CSI1_SCLK]         = &csi1_sclk_clk.common.hw,
 516                [CLK_CSI1_MCLK]         = &csi1_mclk_clk.common.hw,
 517                [CLK_VE]                = &ve_clk.common.hw,
 518                [CLK_AC_DIG]            = &ac_dig_clk.common.hw,
 519                [CLK_AVS]               = &avs_clk.common.hw,
 520                [CLK_MBUS]              = &mbus_clk.common.hw,
 521                [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
 522        },
 523        .num    = CLK_NUMBER,
 524};
 525
 526static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
 527        [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
 528
 529        [RST_MBUS]              =  { 0x0fc, BIT(31) },
 530
 531        [RST_BUS_CE]            =  { 0x2c0, BIT(5) },
 532        [RST_BUS_DMA]           =  { 0x2c0, BIT(6) },
 533        [RST_BUS_MMC0]          =  { 0x2c0, BIT(8) },
 534        [RST_BUS_MMC1]          =  { 0x2c0, BIT(9) },
 535        [RST_BUS_MMC2]          =  { 0x2c0, BIT(10) },
 536        [RST_BUS_DRAM]          =  { 0x2c0, BIT(14) },
 537        [RST_BUS_EMAC]          =  { 0x2c0, BIT(17) },
 538        [RST_BUS_HSTIMER]       =  { 0x2c0, BIT(19) },
 539        [RST_BUS_SPI0]          =  { 0x2c0, BIT(20) },
 540        [RST_BUS_OTG]           =  { 0x2c0, BIT(24) },
 541        [RST_BUS_EHCI0]         =  { 0x2c0, BIT(26) },
 542        [RST_BUS_OHCI0]         =  { 0x2c0, BIT(29) },
 543
 544        [RST_BUS_VE]            =  { 0x2c4, BIT(0) },
 545        [RST_BUS_TCON0]         =  { 0x2c4, BIT(3) },
 546        [RST_BUS_CSI]           =  { 0x2c4, BIT(8) },
 547        [RST_BUS_DE]            =  { 0x2c4, BIT(12) },
 548        [RST_BUS_DBG]           =  { 0x2c4, BIT(31) },
 549
 550        [RST_BUS_EPHY]          =  { 0x2c8, BIT(2) },
 551
 552        [RST_BUS_CODEC]         =  { 0x2d0, BIT(0) },
 553
 554        [RST_BUS_I2C0]          =  { 0x2d8, BIT(0) },
 555        [RST_BUS_I2C1]          =  { 0x2d8, BIT(1) },
 556        [RST_BUS_UART0]         =  { 0x2d8, BIT(16) },
 557        [RST_BUS_UART1]         =  { 0x2d8, BIT(17) },
 558        [RST_BUS_UART2]         =  { 0x2d8, BIT(18) },
 559};
 560
 561static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
 562        .ccu_clks       = sun8i_v3s_ccu_clks,
 563        .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_ccu_clks),
 564
 565        .hw_clks        = &sun8i_v3s_hw_clks,
 566
 567        .resets         = sun8i_v3s_ccu_resets,
 568        .num_resets     = ARRAY_SIZE(sun8i_v3s_ccu_resets),
 569};
 570
 571static void __init sun8i_v3s_ccu_setup(struct device_node *node)
 572{
 573        void __iomem *reg;
 574        u32 val;
 575
 576        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
 577        if (IS_ERR(reg)) {
 578                pr_err("%pOF: Could not map the clock registers\n", node);
 579                return;
 580        }
 581
 582        /* Force the PLL-Audio-1x divider to 4 */
 583        val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
 584        val &= ~GENMASK(19, 16);
 585        writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG);
 586
 587        sunxi_ccu_probe(node, reg, &sun8i_v3s_ccu_desc);
 588}
 589CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
 590               sun8i_v3s_ccu_setup);
 591