linux/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
   4 *
   5 * Based on ccu-sun8i-h3.c, which is:
   6 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
   7 */
   8
   9#include <linux/clk-provider.h>
  10#include <linux/io.h>
  11#include <linux/of_address.h>
  12
  13#include "ccu_common.h"
  14#include "ccu_reset.h"
  15
  16#include "ccu_div.h"
  17#include "ccu_gate.h"
  18#include "ccu_mp.h"
  19#include "ccu_mult.h"
  20#include "ccu_nk.h"
  21#include "ccu_nkm.h"
  22#include "ccu_nkmp.h"
  23#include "ccu_nm.h"
  24#include "ccu_phase.h"
  25
  26#include "ccu-sun8i-v3s.h"
  27
  28static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
  29                                     "osc24M", 0x000,
  30                                     8, 5,      /* N */
  31                                     4, 2,      /* K */
  32                                     0, 2,      /* M */
  33                                     16, 2,     /* P */
  34                                     BIT(31),   /* gate */
  35                                     BIT(28),   /* lock */
  36                                     0);
  37
  38/*
  39 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
  40 * the base (2x, 4x and 8x), and one variable divider (the one true
  41 * pll audio).
  42 *
  43 * With sigma-delta modulation for fractional-N on the audio PLL,
  44 * we have to use specific dividers. This means the variable divider
  45 * can no longer be used, as the audio codec requests the exact clock
  46 * rates we support through this mechanism. So we now hard code the
  47 * variable divider to 1. This means the clock rates will no longer
  48 * match the clock names.
  49 */
  50#define SUN8I_V3S_PLL_AUDIO_REG 0x008
  51
  52static struct ccu_sdm_setting pll_audio_sdm_table[] = {
  53        { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
  54        { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
  55};
  56
  57static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
  58                                       "osc24M", 0x008,
  59                                       8, 7,    /* N */
  60                                       0, 5,    /* M */
  61                                       pll_audio_sdm_table, BIT(24),
  62                                       0x284, BIT(31),
  63                                       BIT(31), /* gate */
  64                                       BIT(28), /* lock */
  65                                       CLK_SET_RATE_UNGATE);
  66
  67static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
  68                                        "osc24M", 0x0010,
  69                                        8, 7,           /* N */
  70                                        0, 4,           /* M */
  71                                        BIT(24),        /* frac enable */
  72                                        BIT(25),        /* frac select */
  73                                        270000000,      /* frac rate 0 */
  74                                        297000000,      /* frac rate 1 */
  75                                        BIT(31),        /* gate */
  76                                        BIT(28),        /* lock */
  77                                        0);
  78
  79static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
  80                                        "osc24M", 0x0018,
  81                                        8, 7,           /* N */
  82                                        0, 4,           /* M */
  83                                        BIT(24),        /* frac enable */
  84                                        BIT(25),        /* frac select */
  85                                        270000000,      /* frac rate 0 */
  86                                        297000000,      /* frac rate 1 */
  87                                        BIT(31),        /* gate */
  88                                        BIT(28),        /* lock */
  89                                        0);
  90
  91static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0",
  92                                    "osc24M", 0x020,
  93                                    8, 5,       /* N */
  94                                    4, 2,       /* K */
  95                                    0, 2,       /* M */
  96                                    BIT(31),    /* gate */
  97                                    BIT(28),    /* lock */
  98                                    0);
  99
 100static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
 101                                           "osc24M", 0x028,
 102                                           8, 5,        /* N */
 103                                           4, 2,        /* K */
 104                                           BIT(31),     /* gate */
 105                                           BIT(28),     /* lock */
 106                                           2,           /* post-div */
 107                                           0);
 108
 109static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_isp_clk, "pll-isp",
 110                                        "osc24M", 0x002c,
 111                                        8, 7,           /* N */
 112                                        0, 4,           /* M */
 113                                        BIT(24),        /* frac enable */
 114                                        BIT(25),        /* frac select */
 115                                        270000000,      /* frac rate 0 */
 116                                        297000000,      /* frac rate 1 */
 117                                        BIT(31),        /* gate */
 118                                        BIT(28),        /* lock */
 119                                        0);
 120
 121static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
 122                                           "osc24M", 0x044,
 123                                           8, 5,        /* N */
 124                                           4, 2,        /* K */
 125                                           BIT(31),     /* gate */
 126                                           BIT(28),     /* lock */
 127                                           2,           /* post-div */
 128                                           0);
 129
 130static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
 131                                   "osc24M", 0x04c,
 132                                   8, 7,        /* N */
 133                                   0, 2,        /* M */
 134                                   BIT(31),     /* gate */
 135                                   BIT(28),     /* lock */
 136                                   0);
 137
 138static const char * const cpu_parents[] = { "osc32k", "osc24M",
 139                                             "pll-cpu", "pll-cpu" };
 140static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
 141                     0x050, 16, 2, CLK_IS_CRITICAL);
 142
 143static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
 144
 145static const char * const ahb1_parents[] = { "osc32k", "osc24M",
 146                                             "axi", "pll-periph0" };
 147static const struct ccu_mux_var_prediv ahb1_predivs[] = {
 148        { .index = 3, .shift = 6, .width = 2 },
 149};
 150static struct ccu_div ahb1_clk = {
 151        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 152
 153        .mux            = {
 154                .shift  = 12,
 155                .width  = 2,
 156
 157                .var_predivs    = ahb1_predivs,
 158                .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
 159        },
 160
 161        .common         = {
 162                .reg            = 0x054,
 163                .features       = CCU_FEATURE_VARIABLE_PREDIV,
 164                .hw.init        = CLK_HW_INIT_PARENTS("ahb1",
 165                                                      ahb1_parents,
 166                                                      &ccu_div_ops,
 167                                                      0),
 168        },
 169};
 170
 171static struct clk_div_table apb1_div_table[] = {
 172        { .val = 0, .div = 2 },
 173        { .val = 1, .div = 2 },
 174        { .val = 2, .div = 4 },
 175        { .val = 3, .div = 8 },
 176        { /* Sentinel */ },
 177};
 178static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
 179                           0x054, 8, 2, apb1_div_table, 0);
 180
 181static const char * const apb2_parents[] = { "osc32k", "osc24M",
 182                                             "pll-periph0", "pll-periph0" };
 183static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
 184                             0, 5,      /* M */
 185                             16, 2,     /* P */
 186                             24, 2,     /* mux */
 187                             0);
 188
 189static const char * const ahb2_parents[] = { "ahb1", "pll-periph0" };
 190static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
 191        { .index = 1, .div = 2 },
 192};
 193static struct ccu_mux ahb2_clk = {
 194        .mux            = {
 195                .shift  = 0,
 196                .width  = 1,
 197                .fixed_predivs  = ahb2_fixed_predivs,
 198                .n_predivs      = ARRAY_SIZE(ahb2_fixed_predivs),
 199        },
 200
 201        .common         = {
 202                .reg            = 0x05c,
 203                .features       = CCU_FEATURE_FIXED_PREDIV,
 204                .hw.init        = CLK_HW_INIT_PARENTS("ahb2",
 205                                                      ahb2_parents,
 206                                                      &ccu_mux_ops,
 207                                                      0),
 208        },
 209};
 210
 211static SUNXI_CCU_GATE(bus_ce_clk,       "bus-ce",       "ahb1",
 212                      0x060, BIT(5), 0);
 213static SUNXI_CCU_GATE(bus_dma_clk,      "bus-dma",      "ahb1",
 214                      0x060, BIT(6), 0);
 215static SUNXI_CCU_GATE(bus_mmc0_clk,     "bus-mmc0",     "ahb1",
 216                      0x060, BIT(8), 0);
 217static SUNXI_CCU_GATE(bus_mmc1_clk,     "bus-mmc1",     "ahb1",
 218                      0x060, BIT(9), 0);
 219static SUNXI_CCU_GATE(bus_mmc2_clk,     "bus-mmc2",     "ahb1",
 220                      0x060, BIT(10), 0);
 221static SUNXI_CCU_GATE(bus_dram_clk,     "bus-dram",     "ahb1",
 222                      0x060, BIT(14), 0);
 223static SUNXI_CCU_GATE(bus_emac_clk,     "bus-emac",     "ahb2",
 224                      0x060, BIT(17), 0);
 225static SUNXI_CCU_GATE(bus_hstimer_clk,  "bus-hstimer",  "ahb1",
 226                      0x060, BIT(19), 0);
 227static SUNXI_CCU_GATE(bus_spi0_clk,     "bus-spi0",     "ahb1",
 228                      0x060, BIT(20), 0);
 229static SUNXI_CCU_GATE(bus_otg_clk,      "bus-otg",      "ahb1",
 230                      0x060, BIT(24), 0);
 231static SUNXI_CCU_GATE(bus_ehci0_clk,    "bus-ehci0",    "ahb1",
 232                      0x060, BIT(26), 0);
 233static SUNXI_CCU_GATE(bus_ohci0_clk,    "bus-ohci0",    "ahb1",
 234                      0x060, BIT(29), 0);
 235
 236static SUNXI_CCU_GATE(bus_ve_clk,       "bus-ve",       "ahb1",
 237                      0x064, BIT(0), 0);
 238static SUNXI_CCU_GATE(bus_tcon0_clk,    "bus-tcon0",    "ahb1",
 239                      0x064, BIT(4), 0);
 240static SUNXI_CCU_GATE(bus_csi_clk,      "bus-csi",      "ahb1",
 241                      0x064, BIT(8), 0);
 242static SUNXI_CCU_GATE(bus_de_clk,       "bus-de",       "ahb1",
 243                      0x064, BIT(12), 0);
 244
 245static SUNXI_CCU_GATE(bus_codec_clk,    "bus-codec",    "apb1",
 246                      0x068, BIT(0), 0);
 247static SUNXI_CCU_GATE(bus_pio_clk,      "bus-pio",      "apb1",
 248                      0x068, BIT(5), 0);
 249static SUNXI_CCU_GATE(bus_i2s0_clk,     "bus-i2s0",     "apb1",
 250                      0x068, BIT(12), 0);
 251
 252static SUNXI_CCU_GATE(bus_i2c0_clk,     "bus-i2c0",     "apb2",
 253                      0x06c, BIT(0), 0);
 254static SUNXI_CCU_GATE(bus_i2c1_clk,     "bus-i2c1",     "apb2",
 255                      0x06c, BIT(1), 0);
 256static SUNXI_CCU_GATE(bus_uart0_clk,    "bus-uart0",    "apb2",
 257                      0x06c, BIT(16), 0);
 258static SUNXI_CCU_GATE(bus_uart1_clk,    "bus-uart1",    "apb2",
 259                      0x06c, BIT(17), 0);
 260static SUNXI_CCU_GATE(bus_uart2_clk,    "bus-uart2",    "apb2",
 261                      0x06c, BIT(18), 0);
 262
 263static SUNXI_CCU_GATE(bus_ephy_clk,     "bus-ephy",     "ahb1",
 264                      0x070, BIT(0), 0);
 265static SUNXI_CCU_GATE(bus_dbg_clk,      "bus-dbg",      "ahb1",
 266                      0x070, BIT(7), 0);
 267
 268static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
 269                                                     "pll-periph1" };
 270static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
 271                                  0, 4,         /* M */
 272                                  16, 2,        /* P */
 273                                  24, 2,        /* mux */
 274                                  BIT(31),      /* gate */
 275                                  0);
 276
 277static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
 278                       0x088, 20, 3, 0);
 279static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
 280                       0x088, 8, 3, 0);
 281
 282static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
 283                                  0, 4,         /* M */
 284                                  16, 2,        /* P */
 285                                  24, 2,        /* mux */
 286                                  BIT(31),      /* gate */
 287                                  0);
 288
 289static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
 290                       0x08c, 20, 3, 0);
 291static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
 292                       0x08c, 8, 3, 0);
 293
 294static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
 295                                  0, 4,         /* M */
 296                                  16, 2,        /* P */
 297                                  24, 2,        /* mux */
 298                                  BIT(31),      /* gate */
 299                                  0);
 300
 301static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
 302                       0x090, 20, 3, 0);
 303static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
 304                       0x090, 8, 3, 0);
 305
 306static const char * const ce_parents[] = { "osc24M", "pll-periph0", };
 307
 308static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c,
 309                                  0, 4,         /* M */
 310                                  16, 2,        /* P */
 311                                  24, 2,        /* mux */
 312                                  BIT(31),      /* gate */
 313                                  0);
 314
 315static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
 316                                  0, 4,         /* M */
 317                                  16, 2,        /* P */
 318                                  24, 2,        /* mux */
 319                                  BIT(31),      /* gate */
 320                                  0);
 321
 322static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
 323                                            "pll-audio-2x", "pll-audio" };
 324static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
 325                               0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
 326
 327static SUNXI_CCU_GATE(usb_phy0_clk,     "usb-phy0",     "osc24M",
 328                      0x0cc, BIT(8), 0);
 329static SUNXI_CCU_GATE(usb_ohci0_clk,    "usb-ohci0",    "osc24M",
 330                      0x0cc, BIT(16), 0);
 331
 332static const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1",
 333                                             "pll-periph0-2x" };
 334static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
 335                            0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
 336
 337static SUNXI_CCU_GATE(dram_ve_clk,      "dram-ve",      "dram",
 338                      0x100, BIT(0), 0);
 339static SUNXI_CCU_GATE(dram_csi_clk,     "dram-csi",     "dram",
 340                      0x100, BIT(1), 0);
 341static SUNXI_CCU_GATE(dram_ehci_clk,    "dram-ehci",    "dram",
 342                      0x100, BIT(17), 0);
 343static SUNXI_CCU_GATE(dram_ohci_clk,    "dram-ohci",    "dram",
 344                      0x100, BIT(18), 0);
 345
 346static const char * const de_parents[] = { "pll-video", "pll-periph0" };
 347static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
 348                                 0x104, 0, 4, 24, 2, BIT(31),
 349                                 CLK_SET_RATE_PARENT);
 350
 351static const char * const tcon_parents[] = { "pll-video" };
 352static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
 353                                 0x118, 0, 4, 24, 3, BIT(31), 0);
 354
 355static SUNXI_CCU_GATE(csi_misc_clk,     "csi-misc",     "osc24M",
 356                      0x130, BIT(31), 0);
 357
 358static const char * const csi_mclk_parents[] = { "osc24M", "pll-video",
 359                                                 "pll-periph0", "pll-periph1" };
 360static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
 361                                 0x130, 0, 5, 8, 3, BIT(15), 0);
 362
 363static const char * const csi1_sclk_parents[] = { "pll-video", "pll-isp" };
 364static SUNXI_CCU_M_WITH_MUX_GATE(csi1_sclk_clk, "csi-sclk", csi1_sclk_parents,
 365                                 0x134, 16, 4, 24, 3, BIT(31), 0);
 366
 367static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi-mclk", csi_mclk_parents,
 368                                 0x134, 0, 5, 8, 3, BIT(15), 0);
 369
 370static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
 371                             0x13c, 16, 3, BIT(31), 0);
 372
 373static SUNXI_CCU_GATE(ac_dig_clk,       "ac-dig",       "pll-audio",
 374                      0x140, BIT(31), CLK_SET_RATE_PARENT);
 375static SUNXI_CCU_GATE(avs_clk,          "avs",          "osc24M",
 376                      0x144, BIT(31), 0);
 377
 378static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x",
 379                                             "pll-ddr" };
 380static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
 381                                 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
 382
 383static const char * const mipi_csi_parents[] = { "pll-video", "pll-periph0",
 384                                                 "pll-isp" };
 385static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_clk, "mipi-csi", mipi_csi_parents,
 386                             0x16c, 0, 3, 24, 2, BIT(31), 0);
 387
 388static struct ccu_common *sun8i_v3s_ccu_clks[] = {
 389        &pll_cpu_clk.common,
 390        &pll_audio_base_clk.common,
 391        &pll_video_clk.common,
 392        &pll_ve_clk.common,
 393        &pll_ddr0_clk.common,
 394        &pll_periph0_clk.common,
 395        &pll_isp_clk.common,
 396        &pll_periph1_clk.common,
 397        &pll_ddr1_clk.common,
 398        &cpu_clk.common,
 399        &axi_clk.common,
 400        &ahb1_clk.common,
 401        &apb1_clk.common,
 402        &apb2_clk.common,
 403        &ahb2_clk.common,
 404        &bus_ce_clk.common,
 405        &bus_dma_clk.common,
 406        &bus_mmc0_clk.common,
 407        &bus_mmc1_clk.common,
 408        &bus_mmc2_clk.common,
 409        &bus_dram_clk.common,
 410        &bus_emac_clk.common,
 411        &bus_hstimer_clk.common,
 412        &bus_spi0_clk.common,
 413        &bus_otg_clk.common,
 414        &bus_ehci0_clk.common,
 415        &bus_ohci0_clk.common,
 416        &bus_ve_clk.common,
 417        &bus_tcon0_clk.common,
 418        &bus_csi_clk.common,
 419        &bus_de_clk.common,
 420        &bus_codec_clk.common,
 421        &bus_pio_clk.common,
 422        &bus_i2c0_clk.common,
 423        &bus_i2c1_clk.common,
 424        &bus_uart0_clk.common,
 425        &bus_uart1_clk.common,
 426        &bus_uart2_clk.common,
 427        &bus_ephy_clk.common,
 428        &bus_dbg_clk.common,
 429        &mmc0_clk.common,
 430        &mmc0_sample_clk.common,
 431        &mmc0_output_clk.common,
 432        &mmc1_clk.common,
 433        &mmc1_sample_clk.common,
 434        &mmc1_output_clk.common,
 435        &mmc2_clk.common,
 436        &mmc2_sample_clk.common,
 437        &mmc2_output_clk.common,
 438        &ce_clk.common,
 439        &spi0_clk.common,
 440        &usb_phy0_clk.common,
 441        &usb_ohci0_clk.common,
 442        &dram_clk.common,
 443        &dram_ve_clk.common,
 444        &dram_csi_clk.common,
 445        &dram_ohci_clk.common,
 446        &dram_ehci_clk.common,
 447        &de_clk.common,
 448        &tcon_clk.common,
 449        &csi_misc_clk.common,
 450        &csi0_mclk_clk.common,
 451        &csi1_sclk_clk.common,
 452        &csi1_mclk_clk.common,
 453        &ve_clk.common,
 454        &ac_dig_clk.common,
 455        &avs_clk.common,
 456        &mbus_clk.common,
 457        &mipi_csi_clk.common,
 458};
 459
 460static const struct clk_hw *clk_parent_pll_audio[] = {
 461        &pll_audio_base_clk.common.hw
 462};
 463
 464static struct ccu_common *sun8i_v3_ccu_clks[] = {
 465        &pll_cpu_clk.common,
 466        &pll_audio_base_clk.common,
 467        &pll_video_clk.common,
 468        &pll_ve_clk.common,
 469        &pll_ddr0_clk.common,
 470        &pll_periph0_clk.common,
 471        &pll_isp_clk.common,
 472        &pll_periph1_clk.common,
 473        &pll_ddr1_clk.common,
 474        &cpu_clk.common,
 475        &axi_clk.common,
 476        &ahb1_clk.common,
 477        &apb1_clk.common,
 478        &apb2_clk.common,
 479        &ahb2_clk.common,
 480        &bus_ce_clk.common,
 481        &bus_dma_clk.common,
 482        &bus_mmc0_clk.common,
 483        &bus_mmc1_clk.common,
 484        &bus_mmc2_clk.common,
 485        &bus_dram_clk.common,
 486        &bus_emac_clk.common,
 487        &bus_hstimer_clk.common,
 488        &bus_spi0_clk.common,
 489        &bus_otg_clk.common,
 490        &bus_ehci0_clk.common,
 491        &bus_ohci0_clk.common,
 492        &bus_ve_clk.common,
 493        &bus_tcon0_clk.common,
 494        &bus_csi_clk.common,
 495        &bus_de_clk.common,
 496        &bus_codec_clk.common,
 497        &bus_pio_clk.common,
 498        &bus_i2s0_clk.common,
 499        &bus_i2c0_clk.common,
 500        &bus_i2c1_clk.common,
 501        &bus_uart0_clk.common,
 502        &bus_uart1_clk.common,
 503        &bus_uart2_clk.common,
 504        &bus_ephy_clk.common,
 505        &bus_dbg_clk.common,
 506        &mmc0_clk.common,
 507        &mmc0_sample_clk.common,
 508        &mmc0_output_clk.common,
 509        &mmc1_clk.common,
 510        &mmc1_sample_clk.common,
 511        &mmc1_output_clk.common,
 512        &mmc2_clk.common,
 513        &mmc2_sample_clk.common,
 514        &mmc2_output_clk.common,
 515        &ce_clk.common,
 516        &spi0_clk.common,
 517        &i2s0_clk.common,
 518        &usb_phy0_clk.common,
 519        &usb_ohci0_clk.common,
 520        &dram_clk.common,
 521        &dram_ve_clk.common,
 522        &dram_csi_clk.common,
 523        &dram_ohci_clk.common,
 524        &dram_ehci_clk.common,
 525        &de_clk.common,
 526        &tcon_clk.common,
 527        &csi_misc_clk.common,
 528        &csi0_mclk_clk.common,
 529        &csi1_sclk_clk.common,
 530        &csi1_mclk_clk.common,
 531        &ve_clk.common,
 532        &ac_dig_clk.common,
 533        &avs_clk.common,
 534        &mbus_clk.common,
 535        &mipi_csi_clk.common,
 536};
 537
 538/* We hardcode the divider to 1 for SDM support */
 539static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
 540                            clk_parent_pll_audio,
 541                            1, 1, CLK_SET_RATE_PARENT);
 542static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
 543                            clk_parent_pll_audio,
 544                            2, 1, CLK_SET_RATE_PARENT);
 545static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
 546                            clk_parent_pll_audio,
 547                            1, 1, CLK_SET_RATE_PARENT);
 548static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
 549                            clk_parent_pll_audio,
 550                            1, 2, CLK_SET_RATE_PARENT);
 551static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
 552                           &pll_periph0_clk.common.hw,
 553                           1, 2, 0);
 554
 555static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
 556        .hws    = {
 557                [CLK_PLL_CPU]           = &pll_cpu_clk.common.hw,
 558                [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
 559                [CLK_PLL_AUDIO]         = &pll_audio_clk.hw,
 560                [CLK_PLL_AUDIO_2X]      = &pll_audio_2x_clk.hw,
 561                [CLK_PLL_AUDIO_4X]      = &pll_audio_4x_clk.hw,
 562                [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
 563                [CLK_PLL_VIDEO]         = &pll_video_clk.common.hw,
 564                [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
 565                [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
 566                [CLK_PLL_PERIPH0]       = &pll_periph0_clk.common.hw,
 567                [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
 568                [CLK_PLL_ISP]           = &pll_isp_clk.common.hw,
 569                [CLK_PLL_PERIPH1]       = &pll_periph1_clk.common.hw,
 570                [CLK_PLL_DDR1]          = &pll_ddr1_clk.common.hw,
 571                [CLK_CPU]               = &cpu_clk.common.hw,
 572                [CLK_AXI]               = &axi_clk.common.hw,
 573                [CLK_AHB1]              = &ahb1_clk.common.hw,
 574                [CLK_APB1]              = &apb1_clk.common.hw,
 575                [CLK_APB2]              = &apb2_clk.common.hw,
 576                [CLK_AHB2]              = &ahb2_clk.common.hw,
 577                [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
 578                [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
 579                [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
 580                [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
 581                [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
 582                [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
 583                [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
 584                [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
 585                [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
 586                [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
 587                [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
 588                [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
 589                [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
 590                [CLK_BUS_TCON0]         = &bus_tcon0_clk.common.hw,
 591                [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
 592                [CLK_BUS_DE]            = &bus_de_clk.common.hw,
 593                [CLK_BUS_CODEC]         = &bus_codec_clk.common.hw,
 594                [CLK_BUS_PIO]           = &bus_pio_clk.common.hw,
 595                [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
 596                [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
 597                [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
 598                [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
 599                [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
 600                [CLK_BUS_EPHY]          = &bus_ephy_clk.common.hw,
 601                [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
 602                [CLK_MMC0]              = &mmc0_clk.common.hw,
 603                [CLK_MMC0_SAMPLE]       = &mmc0_sample_clk.common.hw,
 604                [CLK_MMC0_OUTPUT]       = &mmc0_output_clk.common.hw,
 605                [CLK_MMC1]              = &mmc1_clk.common.hw,
 606                [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
 607                [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
 608                [CLK_MMC2]              = &mmc2_clk.common.hw,
 609                [CLK_MMC2_SAMPLE]       = &mmc2_sample_clk.common.hw,
 610                [CLK_MMC2_OUTPUT]       = &mmc2_output_clk.common.hw,
 611                [CLK_CE]                = &ce_clk.common.hw,
 612                [CLK_SPI0]              = &spi0_clk.common.hw,
 613                [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
 614                [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
 615                [CLK_DRAM]              = &dram_clk.common.hw,
 616                [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
 617                [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
 618                [CLK_DRAM_EHCI]         = &dram_ehci_clk.common.hw,
 619                [CLK_DRAM_OHCI]         = &dram_ohci_clk.common.hw,
 620                [CLK_DE]                = &de_clk.common.hw,
 621                [CLK_TCON0]             = &tcon_clk.common.hw,
 622                [CLK_CSI_MISC]          = &csi_misc_clk.common.hw,
 623                [CLK_CSI0_MCLK]         = &csi0_mclk_clk.common.hw,
 624                [CLK_CSI1_SCLK]         = &csi1_sclk_clk.common.hw,
 625                [CLK_CSI1_MCLK]         = &csi1_mclk_clk.common.hw,
 626                [CLK_VE]                = &ve_clk.common.hw,
 627                [CLK_AC_DIG]            = &ac_dig_clk.common.hw,
 628                [CLK_AVS]               = &avs_clk.common.hw,
 629                [CLK_MBUS]              = &mbus_clk.common.hw,
 630                [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
 631        },
 632        .num    = CLK_PLL_DDR1 + 1,
 633};
 634
 635static struct clk_hw_onecell_data sun8i_v3_hw_clks = {
 636        .hws    = {
 637                [CLK_PLL_CPU]           = &pll_cpu_clk.common.hw,
 638                [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
 639                [CLK_PLL_AUDIO]         = &pll_audio_clk.hw,
 640                [CLK_PLL_AUDIO_2X]      = &pll_audio_2x_clk.hw,
 641                [CLK_PLL_AUDIO_4X]      = &pll_audio_4x_clk.hw,
 642                [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
 643                [CLK_PLL_VIDEO]         = &pll_video_clk.common.hw,
 644                [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
 645                [CLK_PLL_DDR0]          = &pll_ddr0_clk.common.hw,
 646                [CLK_PLL_PERIPH0]       = &pll_periph0_clk.common.hw,
 647                [CLK_PLL_PERIPH0_2X]    = &pll_periph0_2x_clk.hw,
 648                [CLK_PLL_ISP]           = &pll_isp_clk.common.hw,
 649                [CLK_PLL_PERIPH1]       = &pll_periph1_clk.common.hw,
 650                [CLK_PLL_DDR1]          = &pll_ddr1_clk.common.hw,
 651                [CLK_CPU]               = &cpu_clk.common.hw,
 652                [CLK_AXI]               = &axi_clk.common.hw,
 653                [CLK_AHB1]              = &ahb1_clk.common.hw,
 654                [CLK_APB1]              = &apb1_clk.common.hw,
 655                [CLK_APB2]              = &apb2_clk.common.hw,
 656                [CLK_AHB2]              = &ahb2_clk.common.hw,
 657                [CLK_BUS_CE]            = &bus_ce_clk.common.hw,
 658                [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
 659                [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
 660                [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
 661                [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
 662                [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
 663                [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
 664                [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
 665                [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
 666                [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
 667                [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
 668                [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
 669                [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
 670                [CLK_BUS_TCON0]         = &bus_tcon0_clk.common.hw,
 671                [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
 672                [CLK_BUS_DE]            = &bus_de_clk.common.hw,
 673                [CLK_BUS_CODEC]         = &bus_codec_clk.common.hw,
 674                [CLK_BUS_PIO]           = &bus_pio_clk.common.hw,
 675                [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
 676                [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
 677                [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
 678                [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
 679                [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
 680                [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
 681                [CLK_BUS_EPHY]          = &bus_ephy_clk.common.hw,
 682                [CLK_BUS_DBG]           = &bus_dbg_clk.common.hw,
 683                [CLK_MMC0]              = &mmc0_clk.common.hw,
 684                [CLK_MMC0_SAMPLE]       = &mmc0_sample_clk.common.hw,
 685                [CLK_MMC0_OUTPUT]       = &mmc0_output_clk.common.hw,
 686                [CLK_MMC1]              = &mmc1_clk.common.hw,
 687                [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
 688                [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
 689                [CLK_MMC2]              = &mmc2_clk.common.hw,
 690                [CLK_MMC2_SAMPLE]       = &mmc2_sample_clk.common.hw,
 691                [CLK_MMC2_OUTPUT]       = &mmc2_output_clk.common.hw,
 692                [CLK_CE]                = &ce_clk.common.hw,
 693                [CLK_SPI0]              = &spi0_clk.common.hw,
 694                [CLK_I2S0]              = &i2s0_clk.common.hw,
 695                [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
 696                [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
 697                [CLK_DRAM]              = &dram_clk.common.hw,
 698                [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
 699                [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
 700                [CLK_DRAM_EHCI]         = &dram_ehci_clk.common.hw,
 701                [CLK_DRAM_OHCI]         = &dram_ohci_clk.common.hw,
 702                [CLK_DE]                = &de_clk.common.hw,
 703                [CLK_TCON0]             = &tcon_clk.common.hw,
 704                [CLK_CSI_MISC]          = &csi_misc_clk.common.hw,
 705                [CLK_CSI0_MCLK]         = &csi0_mclk_clk.common.hw,
 706                [CLK_CSI1_SCLK]         = &csi1_sclk_clk.common.hw,
 707                [CLK_CSI1_MCLK]         = &csi1_mclk_clk.common.hw,
 708                [CLK_VE]                = &ve_clk.common.hw,
 709                [CLK_AC_DIG]            = &ac_dig_clk.common.hw,
 710                [CLK_AVS]               = &avs_clk.common.hw,
 711                [CLK_MBUS]              = &mbus_clk.common.hw,
 712                [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
 713        },
 714        .num    = CLK_I2S0 + 1,
 715};
 716
 717static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
 718        [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
 719
 720        [RST_MBUS]              =  { 0x0fc, BIT(31) },
 721
 722        [RST_BUS_CE]            =  { 0x2c0, BIT(5) },
 723        [RST_BUS_DMA]           =  { 0x2c0, BIT(6) },
 724        [RST_BUS_MMC0]          =  { 0x2c0, BIT(8) },
 725        [RST_BUS_MMC1]          =  { 0x2c0, BIT(9) },
 726        [RST_BUS_MMC2]          =  { 0x2c0, BIT(10) },
 727        [RST_BUS_DRAM]          =  { 0x2c0, BIT(14) },
 728        [RST_BUS_EMAC]          =  { 0x2c0, BIT(17) },
 729        [RST_BUS_HSTIMER]       =  { 0x2c0, BIT(19) },
 730        [RST_BUS_SPI0]          =  { 0x2c0, BIT(20) },
 731        [RST_BUS_OTG]           =  { 0x2c0, BIT(24) },
 732        [RST_BUS_EHCI0]         =  { 0x2c0, BIT(26) },
 733        [RST_BUS_OHCI0]         =  { 0x2c0, BIT(29) },
 734
 735        [RST_BUS_VE]            =  { 0x2c4, BIT(0) },
 736        [RST_BUS_TCON0]         =  { 0x2c4, BIT(4) },
 737        [RST_BUS_CSI]           =  { 0x2c4, BIT(8) },
 738        [RST_BUS_DE]            =  { 0x2c4, BIT(12) },
 739        [RST_BUS_DBG]           =  { 0x2c4, BIT(31) },
 740
 741        [RST_BUS_EPHY]          =  { 0x2c8, BIT(2) },
 742
 743        [RST_BUS_CODEC]         =  { 0x2d0, BIT(0) },
 744
 745        [RST_BUS_I2C0]          =  { 0x2d8, BIT(0) },
 746        [RST_BUS_I2C1]          =  { 0x2d8, BIT(1) },
 747        [RST_BUS_UART0]         =  { 0x2d8, BIT(16) },
 748        [RST_BUS_UART1]         =  { 0x2d8, BIT(17) },
 749        [RST_BUS_UART2]         =  { 0x2d8, BIT(18) },
 750};
 751
 752static struct ccu_reset_map sun8i_v3_ccu_resets[] = {
 753        [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
 754
 755        [RST_MBUS]              =  { 0x0fc, BIT(31) },
 756
 757        [RST_BUS_CE]            =  { 0x2c0, BIT(5) },
 758        [RST_BUS_DMA]           =  { 0x2c0, BIT(6) },
 759        [RST_BUS_MMC0]          =  { 0x2c0, BIT(8) },
 760        [RST_BUS_MMC1]          =  { 0x2c0, BIT(9) },
 761        [RST_BUS_MMC2]          =  { 0x2c0, BIT(10) },
 762        [RST_BUS_DRAM]          =  { 0x2c0, BIT(14) },
 763        [RST_BUS_EMAC]          =  { 0x2c0, BIT(17) },
 764        [RST_BUS_HSTIMER]       =  { 0x2c0, BIT(19) },
 765        [RST_BUS_SPI0]          =  { 0x2c0, BIT(20) },
 766        [RST_BUS_OTG]           =  { 0x2c0, BIT(24) },
 767        [RST_BUS_EHCI0]         =  { 0x2c0, BIT(26) },
 768        [RST_BUS_OHCI0]         =  { 0x2c0, BIT(29) },
 769
 770        [RST_BUS_VE]            =  { 0x2c4, BIT(0) },
 771        [RST_BUS_TCON0]         =  { 0x2c4, BIT(4) },
 772        [RST_BUS_CSI]           =  { 0x2c4, BIT(8) },
 773        [RST_BUS_DE]            =  { 0x2c4, BIT(12) },
 774        [RST_BUS_DBG]           =  { 0x2c4, BIT(31) },
 775
 776        [RST_BUS_EPHY]          =  { 0x2c8, BIT(2) },
 777
 778        [RST_BUS_CODEC]         =  { 0x2d0, BIT(0) },
 779        [RST_BUS_I2S0]          =  { 0x2d0, BIT(12) },
 780
 781        [RST_BUS_I2C0]          =  { 0x2d8, BIT(0) },
 782        [RST_BUS_I2C1]          =  { 0x2d8, BIT(1) },
 783        [RST_BUS_UART0]         =  { 0x2d8, BIT(16) },
 784        [RST_BUS_UART1]         =  { 0x2d8, BIT(17) },
 785        [RST_BUS_UART2]         =  { 0x2d8, BIT(18) },
 786};
 787
 788static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
 789        .ccu_clks       = sun8i_v3s_ccu_clks,
 790        .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_ccu_clks),
 791
 792        .hw_clks        = &sun8i_v3s_hw_clks,
 793
 794        .resets         = sun8i_v3s_ccu_resets,
 795        .num_resets     = ARRAY_SIZE(sun8i_v3s_ccu_resets),
 796};
 797
 798static const struct sunxi_ccu_desc sun8i_v3_ccu_desc = {
 799        .ccu_clks       = sun8i_v3_ccu_clks,
 800        .num_ccu_clks   = ARRAY_SIZE(sun8i_v3_ccu_clks),
 801
 802        .hw_clks        = &sun8i_v3_hw_clks,
 803
 804        .resets         = sun8i_v3_ccu_resets,
 805        .num_resets     = ARRAY_SIZE(sun8i_v3_ccu_resets),
 806};
 807
 808static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
 809                                         const struct sunxi_ccu_desc *ccu_desc)
 810{
 811        void __iomem *reg;
 812        u32 val;
 813
 814        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
 815        if (IS_ERR(reg)) {
 816                pr_err("%pOF: Could not map the clock registers\n", node);
 817                return;
 818        }
 819
 820        /* Force the PLL-Audio-1x divider to 1 */
 821        val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
 822        val &= ~GENMASK(19, 16);
 823        writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
 824
 825        sunxi_ccu_probe(node, reg, ccu_desc);
 826}
 827
 828static void __init sun8i_v3s_ccu_setup(struct device_node *node)
 829{
 830        sun8i_v3_v3s_ccu_init(node, &sun8i_v3s_ccu_desc);
 831}
 832
 833static void __init sun8i_v3_ccu_setup(struct device_node *node)
 834{
 835        sun8i_v3_v3s_ccu_init(node, &sun8i_v3_ccu_desc);
 836}
 837
 838CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
 839               sun8i_v3s_ccu_setup);
 840
 841CLK_OF_DECLARE(sun8i_v3_ccu, "allwinner,sun8i-v3-ccu",
 842               sun8i_v3_ccu_setup);
 843