linux/drivers/clk/rockchip/clk.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * Copyright (c) 2014 MundoReader S.L.
   4 * Author: Heiko Stuebner <heiko@sntech.de>
   5 *
   6 * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
   7 * Author: Xing Zheng <zhengxing@rock-chips.com>
   8 *
   9 * based on
  10 *
  11 * samsung/clk.h
  12 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  13 * Copyright (c) 2013 Linaro Ltd.
  14 * Author: Thomas Abraham <thomas.ab@samsung.com>
  15 */
  16
  17#ifndef CLK_ROCKCHIP_CLK_H
  18#define CLK_ROCKCHIP_CLK_H
  19
  20#include <linux/io.h>
  21#include <linux/clk-provider.h>
  22
  23struct clk;
  24
  25#define HIWORD_UPDATE(val, mask, shift) \
  26                ((val) << (shift) | (mask) << ((shift) + 16))
  27
  28/* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
  29#define BOOST_PLL_H_CON(x)              ((x) * 0x4)
  30#define BOOST_CLK_CON                   0x0008
  31#define BOOST_BOOST_CON                 0x000c
  32#define BOOST_SWITCH_CNT                0x0010
  33#define BOOST_HIGH_PERF_CNT0            0x0014
  34#define BOOST_HIGH_PERF_CNT1            0x0018
  35#define BOOST_STATIS_THRESHOLD          0x001c
  36#define BOOST_SHORT_SWITCH_CNT          0x0020
  37#define BOOST_SWITCH_THRESHOLD          0x0024
  38#define BOOST_FSM_STATUS                0x0028
  39#define BOOST_PLL_L_CON(x)              ((x) * 0x4 + 0x2c)
  40#define BOOST_RECOVERY_MASK             0x1
  41#define BOOST_RECOVERY_SHIFT            1
  42#define BOOST_SW_CTRL_MASK              0x1
  43#define BOOST_SW_CTRL_SHIFT             2
  44#define BOOST_LOW_FREQ_EN_MASK          0x1
  45#define BOOST_LOW_FREQ_EN_SHIFT         3
  46#define BOOST_BUSY_STATE                BIT(8)
  47
  48#define PX30_PLL_CON(x)                 ((x) * 0x4)
  49#define PX30_CLKSEL_CON(x)              ((x) * 0x4 + 0x100)
  50#define PX30_CLKGATE_CON(x)             ((x) * 0x4 + 0x200)
  51#define PX30_GLB_SRST_FST               0xb8
  52#define PX30_GLB_SRST_SND               0xbc
  53#define PX30_SOFTRST_CON(x)             ((x) * 0x4 + 0x300)
  54#define PX30_MODE_CON                   0xa0
  55#define PX30_MISC_CON                   0xa4
  56#define PX30_SDMMC_CON0                 0x380
  57#define PX30_SDMMC_CON1                 0x384
  58#define PX30_SDIO_CON0                  0x388
  59#define PX30_SDIO_CON1                  0x38c
  60#define PX30_EMMC_CON0                  0x390
  61#define PX30_EMMC_CON1                  0x394
  62
  63#define PX30_PMU_PLL_CON(x)             ((x) * 0x4)
  64#define PX30_PMU_CLKSEL_CON(x)          ((x) * 0x4 + 0x40)
  65#define PX30_PMU_CLKGATE_CON(x)         ((x) * 0x4 + 0x80)
  66#define PX30_PMU_MODE                   0x0020
  67
  68#define RV1108_PLL_CON(x)               ((x) * 0x4)
  69#define RV1108_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
  70#define RV1108_CLKGATE_CON(x)           ((x) * 0x4 + 0x120)
  71#define RV1108_SOFTRST_CON(x)           ((x) * 0x4 + 0x180)
  72#define RV1108_GLB_SRST_FST             0x1c0
  73#define RV1108_GLB_SRST_SND             0x1c4
  74#define RV1108_MISC_CON                 0x1cc
  75#define RV1108_SDMMC_CON0               0x1d8
  76#define RV1108_SDMMC_CON1               0x1dc
  77#define RV1108_SDIO_CON0                0x1e0
  78#define RV1108_SDIO_CON1                0x1e4
  79#define RV1108_EMMC_CON0                0x1e8
  80#define RV1108_EMMC_CON1                0x1ec
  81
  82#define RK2928_PLL_CON(x)               ((x) * 0x4)
  83#define RK2928_MODE_CON         0x40
  84#define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
  85#define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
  86#define RK2928_GLB_SRST_FST             0x100
  87#define RK2928_GLB_SRST_SND             0x104
  88#define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
  89#define RK2928_MISC_CON         0x134
  90
  91#define RK3036_SDMMC_CON0               0x144
  92#define RK3036_SDMMC_CON1               0x148
  93#define RK3036_SDIO_CON0                0x14c
  94#define RK3036_SDIO_CON1                0x150
  95#define RK3036_EMMC_CON0                0x154
  96#define RK3036_EMMC_CON1                0x158
  97
  98#define RK3228_GLB_SRST_FST             0x1f0
  99#define RK3228_GLB_SRST_SND             0x1f4
 100#define RK3228_SDMMC_CON0               0x1c0
 101#define RK3228_SDMMC_CON1               0x1c4
 102#define RK3228_SDIO_CON0                0x1c8
 103#define RK3228_SDIO_CON1                0x1cc
 104#define RK3228_EMMC_CON0                0x1d8
 105#define RK3228_EMMC_CON1                0x1dc
 106
 107#define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
 108#define RK3288_MODE_CON                 0x50
 109#define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
 110#define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
 111#define RK3288_GLB_SRST_FST             0x1b0
 112#define RK3288_GLB_SRST_SND             0x1b4
 113#define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
 114#define RK3288_MISC_CON                 0x1e8
 115#define RK3288_SDMMC_CON0               0x200
 116#define RK3288_SDMMC_CON1               0x204
 117#define RK3288_SDIO0_CON0               0x208
 118#define RK3288_SDIO0_CON1               0x20c
 119#define RK3288_SDIO1_CON0               0x210
 120#define RK3288_SDIO1_CON1               0x214
 121#define RK3288_EMMC_CON0                0x218
 122#define RK3288_EMMC_CON1                0x21c
 123
 124#define RK3308_PLL_CON(x)               RK2928_PLL_CON(x)
 125#define RK3308_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 126#define RK3308_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
 127#define RK3308_GLB_SRST_FST             0xb8
 128#define RK3308_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
 129#define RK3308_MODE_CON                 0xa0
 130#define RK3308_SDMMC_CON0               0x480
 131#define RK3308_SDMMC_CON1               0x484
 132#define RK3308_SDIO_CON0                0x488
 133#define RK3308_SDIO_CON1                0x48c
 134#define RK3308_EMMC_CON0                0x490
 135#define RK3308_EMMC_CON1                0x494
 136
 137#define RK3328_PLL_CON(x)               RK2928_PLL_CON(x)
 138#define RK3328_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 139#define RK3328_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
 140#define RK3328_GRFCLKSEL_CON(x)         ((x) * 0x4 + 0x100)
 141#define RK3328_GLB_SRST_FST             0x9c
 142#define RK3328_GLB_SRST_SND             0x98
 143#define RK3328_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
 144#define RK3328_MODE_CON                 0x80
 145#define RK3328_MISC_CON                 0x84
 146#define RK3328_SDMMC_CON0               0x380
 147#define RK3328_SDMMC_CON1               0x384
 148#define RK3328_SDIO_CON0                0x388
 149#define RK3328_SDIO_CON1                0x38c
 150#define RK3328_EMMC_CON0                0x390
 151#define RK3328_EMMC_CON1                0x394
 152#define RK3328_SDMMC_EXT_CON0           0x398
 153#define RK3328_SDMMC_EXT_CON1           0x39C
 154
 155#define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
 156#define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 157#define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
 158#define RK3368_GLB_SRST_FST             0x280
 159#define RK3368_GLB_SRST_SND             0x284
 160#define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
 161#define RK3368_MISC_CON                 0x380
 162#define RK3368_SDMMC_CON0               0x400
 163#define RK3368_SDMMC_CON1               0x404
 164#define RK3368_SDIO0_CON0               0x408
 165#define RK3368_SDIO0_CON1               0x40c
 166#define RK3368_SDIO1_CON0               0x410
 167#define RK3368_SDIO1_CON1               0x414
 168#define RK3368_EMMC_CON0                0x418
 169#define RK3368_EMMC_CON1                0x41c
 170
 171#define RK3399_PLL_CON(x)               RK2928_PLL_CON(x)
 172#define RK3399_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 173#define RK3399_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
 174#define RK3399_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
 175#define RK3399_GLB_SRST_FST             0x500
 176#define RK3399_GLB_SRST_SND             0x504
 177#define RK3399_GLB_CNT_TH               0x508
 178#define RK3399_MISC_CON                 0x50c
 179#define RK3399_RST_CON                  0x510
 180#define RK3399_RST_ST                   0x514
 181#define RK3399_SDMMC_CON0               0x580
 182#define RK3399_SDMMC_CON1               0x584
 183#define RK3399_SDIO_CON0                0x588
 184#define RK3399_SDIO_CON1                0x58c
 185
 186#define RK3399_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
 187#define RK3399_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x80)
 188#define RK3399_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x100)
 189#define RK3399_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x110)
 190
 191#define RK3568_PLL_CON(x)               RK2928_PLL_CON(x)
 192#define RK3568_MODE_CON0                0xc0
 193#define RK3568_MISC_CON0                0xc4
 194#define RK3568_MISC_CON1                0xc8
 195#define RK3568_MISC_CON2                0xcc
 196#define RK3568_GLB_CNT_TH               0xd0
 197#define RK3568_GLB_SRST_FST             0xd4
 198#define RK3568_GLB_SRST_SND             0xd8
 199#define RK3568_GLB_RST_CON              0xdc
 200#define RK3568_GLB_RST_ST               0xe0
 201#define RK3568_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 202#define RK3568_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
 203#define RK3568_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
 204#define RK3568_SDMMC0_CON0              0x580
 205#define RK3568_SDMMC0_CON1              0x584
 206#define RK3568_SDMMC1_CON0              0x588
 207#define RK3568_SDMMC1_CON1              0x58c
 208#define RK3568_SDMMC2_CON0              0x590
 209#define RK3568_SDMMC2_CON1              0x594
 210#define RK3568_EMMC_CON0                0x598
 211#define RK3568_EMMC_CON1                0x59c
 212
 213#define RK3568_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
 214#define RK3568_PMU_MODE_CON0            0x80
 215#define RK3568_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
 216#define RK3568_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x180)
 217#define RK3568_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x200)
 218
 219enum rockchip_pll_type {
 220        pll_rk3036,
 221        pll_rk3066,
 222        pll_rk3328,
 223        pll_rk3399,
 224};
 225
 226#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
 227                        _postdiv2, _dsmpd, _frac)               \
 228{                                                               \
 229        .rate   = _rate##U,                                     \
 230        .fbdiv = _fbdiv,                                        \
 231        .postdiv1 = _postdiv1,                                  \
 232        .refdiv = _refdiv,                                      \
 233        .postdiv2 = _postdiv2,                                  \
 234        .dsmpd = _dsmpd,                                        \
 235        .frac = _frac,                                          \
 236}
 237
 238#define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
 239{                                               \
 240        .rate   = _rate##U,                     \
 241        .nr = _nr,                              \
 242        .nf = _nf,                              \
 243        .no = _no,                              \
 244        .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
 245}
 246
 247#define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
 248{                                                               \
 249        .rate   = _rate##U,                                     \
 250        .nr = _nr,                                              \
 251        .nf = _nf,                                              \
 252        .no = _no,                                              \
 253        .nb = _nb,                                              \
 254}
 255
 256/**
 257 * struct rockchip_clk_provider - information about clock provider
 258 * @reg_base: virtual address for the register base.
 259 * @clk_data: holds clock related data like clk* and number of clocks.
 260 * @cru_node: device-node of the clock-provider
 261 * @grf: regmap of the general-register-files syscon
 262 * @lock: maintains exclusion between callbacks for a given clock-provider.
 263 */
 264struct rockchip_clk_provider {
 265        void __iomem *reg_base;
 266        struct clk_onecell_data clk_data;
 267        struct device_node *cru_node;
 268        struct regmap *grf;
 269        spinlock_t lock;
 270};
 271
 272struct rockchip_pll_rate_table {
 273        unsigned long rate;
 274        union {
 275                struct {
 276                        /* for RK3066 */
 277                        unsigned int nr;
 278                        unsigned int nf;
 279                        unsigned int no;
 280                        unsigned int nb;
 281                };
 282                struct {
 283                        /* for RK3036/RK3399 */
 284                        unsigned int fbdiv;
 285                        unsigned int postdiv1;
 286                        unsigned int refdiv;
 287                        unsigned int postdiv2;
 288                        unsigned int dsmpd;
 289                        unsigned int frac;
 290                };
 291        };
 292};
 293
 294/**
 295 * struct rockchip_pll_clock - information about pll clock
 296 * @id: platform specific id of the clock.
 297 * @name: name of this pll clock.
 298 * @parent_names: name of the parent clock.
 299 * @num_parents: number of parents
 300 * @flags: optional flags for basic clock.
 301 * @con_offset: offset of the register for configuring the PLL.
 302 * @mode_offset: offset of the register for configuring the PLL-mode.
 303 * @mode_shift: offset inside the mode-register for the mode of this pll.
 304 * @lock_shift: offset inside the lock register for the lock status.
 305 * @type: Type of PLL to be registered.
 306 * @pll_flags: hardware-specific flags
 307 * @rate_table: Table of usable pll rates
 308 *
 309 * Flags:
 310 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
 311 *      rate_table parameters and ajust them if necessary.
 312 */
 313struct rockchip_pll_clock {
 314        unsigned int            id;
 315        const char              *name;
 316        const char              *const *parent_names;
 317        u8                      num_parents;
 318        unsigned long           flags;
 319        int                     con_offset;
 320        int                     mode_offset;
 321        int                     mode_shift;
 322        int                     lock_shift;
 323        enum rockchip_pll_type  type;
 324        u8                      pll_flags;
 325        struct rockchip_pll_rate_table *rate_table;
 326};
 327
 328#define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
 329
 330#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
 331                _lshift, _pflags, _rtable)                              \
 332        {                                                               \
 333                .id             = _id,                                  \
 334                .type           = _type,                                \
 335                .name           = _name,                                \
 336                .parent_names   = _pnames,                              \
 337                .num_parents    = ARRAY_SIZE(_pnames),                  \
 338                .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
 339                .con_offset     = _con,                                 \
 340                .mode_offset    = _mode,                                \
 341                .mode_shift     = _mshift,                              \
 342                .lock_shift     = _lshift,                              \
 343                .pll_flags      = _pflags,                              \
 344                .rate_table     = _rtable,                              \
 345        }
 346
 347struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
 348                enum rockchip_pll_type pll_type,
 349                const char *name, const char *const *parent_names,
 350                u8 num_parents, int con_offset, int grf_lock_offset,
 351                int lock_shift, int mode_offset, int mode_shift,
 352                struct rockchip_pll_rate_table *rate_table,
 353                unsigned long flags, u8 clk_pll_flags);
 354
 355struct rockchip_cpuclk_clksel {
 356        int reg;
 357        u32 val;
 358};
 359
 360#define ROCKCHIP_CPUCLK_NUM_DIVIDERS    5
 361#define ROCKCHIP_CPUCLK_MAX_CORES       4
 362struct rockchip_cpuclk_rate_table {
 363        unsigned long prate;
 364        struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
 365};
 366
 367/**
 368 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
 369 * @core_reg[]: register offset of the cores setting register
 370 * @div_core_shift[]:   cores divider offset used to divide the pll value
 371 * @div_core_mask[]:    cores divider mask
 372 * @num_cores:  number of cpu cores
 373 * @mux_core_main:      mux value to select main parent of core
 374 * @mux_core_shift:     offset of the core multiplexer
 375 * @mux_core_mask:      core multiplexer mask
 376 */
 377struct rockchip_cpuclk_reg_data {
 378        int     core_reg[ROCKCHIP_CPUCLK_MAX_CORES];
 379        u8      div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES];
 380        u32     div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES];
 381        int     num_cores;
 382        u8      mux_core_alt;
 383        u8      mux_core_main;
 384        u8      mux_core_shift;
 385        u32     mux_core_mask;
 386};
 387
 388struct clk *rockchip_clk_register_cpuclk(const char *name,
 389                        const char *const *parent_names, u8 num_parents,
 390                        const struct rockchip_cpuclk_reg_data *reg_data,
 391                        const struct rockchip_cpuclk_rate_table *rates,
 392                        int nrates, void __iomem *reg_base, spinlock_t *lock);
 393
 394struct clk *rockchip_clk_register_mmc(const char *name,
 395                                const char *const *parent_names, u8 num_parents,
 396                                void __iomem *reg, int shift);
 397
 398/*
 399 * DDRCLK flags, including method of setting the rate
 400 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
 401 */
 402#define ROCKCHIP_DDRCLK_SIP             BIT(0)
 403
 404struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
 405                                         const char *const *parent_names,
 406                                         u8 num_parents, int mux_offset,
 407                                         int mux_shift, int mux_width,
 408                                         int div_shift, int div_width,
 409                                         int ddr_flags, void __iomem *reg_base,
 410                                         spinlock_t *lock);
 411
 412#define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
 413
 414struct clk *rockchip_clk_register_inverter(const char *name,
 415                                const char *const *parent_names, u8 num_parents,
 416                                void __iomem *reg, int shift, int flags,
 417                                spinlock_t *lock);
 418
 419struct clk *rockchip_clk_register_muxgrf(const char *name,
 420                                const char *const *parent_names, u8 num_parents,
 421                                int flags, struct regmap *grf, int reg,
 422                                int shift, int width, int mux_flags);
 423
 424#define PNAME(x) static const char *const x[] __initconst
 425
 426enum rockchip_clk_branch_type {
 427        branch_composite,
 428        branch_mux,
 429        branch_muxgrf,
 430        branch_divider,
 431        branch_fraction_divider,
 432        branch_gate,
 433        branch_mmc,
 434        branch_inverter,
 435        branch_factor,
 436        branch_ddrclk,
 437        branch_half_divider,
 438};
 439
 440struct rockchip_clk_branch {
 441        unsigned int                    id;
 442        enum rockchip_clk_branch_type   branch_type;
 443        const char                      *name;
 444        const char                      *const *parent_names;
 445        u8                              num_parents;
 446        unsigned long                   flags;
 447        int                             muxdiv_offset;
 448        u8                              mux_shift;
 449        u8                              mux_width;
 450        u8                              mux_flags;
 451        int                             div_offset;
 452        u8                              div_shift;
 453        u8                              div_width;
 454        u8                              div_flags;
 455        struct clk_div_table            *div_table;
 456        int                             gate_offset;
 457        u8                              gate_shift;
 458        u8                              gate_flags;
 459        struct rockchip_clk_branch      *child;
 460};
 461
 462#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
 463                  df, go, gs, gf)                               \
 464        {                                                       \
 465                .id             = _id,                          \
 466                .branch_type    = branch_composite,             \
 467                .name           = cname,                        \
 468                .parent_names   = pnames,                       \
 469                .num_parents    = ARRAY_SIZE(pnames),           \
 470                .flags          = f,                            \
 471                .muxdiv_offset  = mo,                           \
 472                .mux_shift      = ms,                           \
 473                .mux_width      = mw,                           \
 474                .mux_flags      = mf,                           \
 475                .div_shift      = ds,                           \
 476                .div_width      = dw,                           \
 477                .div_flags      = df,                           \
 478                .gate_offset    = go,                           \
 479                .gate_shift     = gs,                           \
 480                .gate_flags     = gf,                           \
 481        }
 482
 483#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
 484                             mf, do, ds, dw, df, go, gs, gf)    \
 485        {                                                       \
 486                .id             = _id,                          \
 487                .branch_type    = branch_composite,             \
 488                .name           = cname,                        \
 489                .parent_names   = pnames,                       \
 490                .num_parents    = ARRAY_SIZE(pnames),           \
 491                .flags          = f,                            \
 492                .muxdiv_offset  = mo,                           \
 493                .mux_shift      = ms,                           \
 494                .mux_width      = mw,                           \
 495                .mux_flags      = mf,                           \
 496                .div_offset     = do,                           \
 497                .div_shift      = ds,                           \
 498                .div_width      = dw,                           \
 499                .div_flags      = df,                           \
 500                .gate_offset    = go,                           \
 501                .gate_shift     = gs,                           \
 502                .gate_flags     = gf,                           \
 503        }
 504
 505#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
 506                        go, gs, gf)                             \
 507        {                                                       \
 508                .id             = _id,                          \
 509                .branch_type    = branch_composite,             \
 510                .name           = cname,                        \
 511                .parent_names   = (const char *[]){ pname },    \
 512                .num_parents    = 1,                            \
 513                .flags          = f,                            \
 514                .muxdiv_offset  = mo,                           \
 515                .div_shift      = ds,                           \
 516                .div_width      = dw,                           \
 517                .div_flags      = df,                           \
 518                .gate_offset    = go,                           \
 519                .gate_shift     = gs,                           \
 520                .gate_flags     = gf,                           \
 521        }
 522
 523#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
 524                               df, dt, go, gs, gf)              \
 525        {                                                       \
 526                .id             = _id,                          \
 527                .branch_type    = branch_composite,             \
 528                .name           = cname,                        \
 529                .parent_names   = (const char *[]){ pname },    \
 530                .num_parents    = 1,                            \
 531                .flags          = f,                            \
 532                .muxdiv_offset  = mo,                           \
 533                .div_shift      = ds,                           \
 534                .div_width      = dw,                           \
 535                .div_flags      = df,                           \
 536                .div_table      = dt,                           \
 537                .gate_offset    = go,                           \
 538                .gate_shift     = gs,                           \
 539                .gate_flags     = gf,                           \
 540        }
 541
 542#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
 543                        go, gs, gf)                             \
 544        {                                                       \
 545                .id             = _id,                          \
 546                .branch_type    = branch_composite,             \
 547                .name           = cname,                        \
 548                .parent_names   = pnames,                       \
 549                .num_parents    = ARRAY_SIZE(pnames),           \
 550                .flags          = f,                            \
 551                .muxdiv_offset  = mo,                           \
 552                .mux_shift      = ms,                           \
 553                .mux_width      = mw,                           \
 554                .mux_flags      = mf,                           \
 555                .gate_offset    = go,                           \
 556                .gate_shift     = gs,                           \
 557                .gate_flags     = gf,                           \
 558        }
 559
 560#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
 561                         ds, dw, df)                            \
 562        {                                                       \
 563                .id             = _id,                          \
 564                .branch_type    = branch_composite,             \
 565                .name           = cname,                        \
 566                .parent_names   = pnames,                       \
 567                .num_parents    = ARRAY_SIZE(pnames),           \
 568                .flags          = f,                            \
 569                .muxdiv_offset  = mo,                           \
 570                .mux_shift      = ms,                           \
 571                .mux_width      = mw,                           \
 572                .mux_flags      = mf,                           \
 573                .div_shift      = ds,                           \
 574                .div_width      = dw,                           \
 575                .div_flags      = df,                           \
 576                .gate_offset    = -1,                           \
 577        }
 578
 579#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
 580                                mw, mf, ds, dw, df, dt)         \
 581        {                                                       \
 582                .id             = _id,                          \
 583                .branch_type    = branch_composite,             \
 584                .name           = cname,                        \
 585                .parent_names   = pnames,                       \
 586                .num_parents    = ARRAY_SIZE(pnames),           \
 587                .flags          = f,                            \
 588                .muxdiv_offset  = mo,                           \
 589                .mux_shift      = ms,                           \
 590                .mux_width      = mw,                           \
 591                .mux_flags      = mf,                           \
 592                .div_shift      = ds,                           \
 593                .div_width      = dw,                           \
 594                .div_flags      = df,                           \
 595                .div_table      = dt,                           \
 596                .gate_offset    = -1,                           \
 597        }
 598
 599#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
 600        {                                                       \
 601                .id             = _id,                          \
 602                .branch_type    = branch_fraction_divider,      \
 603                .name           = cname,                        \
 604                .parent_names   = (const char *[]){ pname },    \
 605                .num_parents    = 1,                            \
 606                .flags          = f,                            \
 607                .muxdiv_offset  = mo,                           \
 608                .div_shift      = 16,                           \
 609                .div_width      = 16,                           \
 610                .div_flags      = df,                           \
 611                .gate_offset    = go,                           \
 612                .gate_shift     = gs,                           \
 613                .gate_flags     = gf,                           \
 614        }
 615
 616#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
 617        {                                                       \
 618                .id             = _id,                          \
 619                .branch_type    = branch_fraction_divider,      \
 620                .name           = cname,                        \
 621                .parent_names   = (const char *[]){ pname },    \
 622                .num_parents    = 1,                            \
 623                .flags          = f,                            \
 624                .muxdiv_offset  = mo,                           \
 625                .div_shift      = 16,                           \
 626                .div_width      = 16,                           \
 627                .div_flags      = df,                           \
 628                .gate_offset    = go,                           \
 629                .gate_shift     = gs,                           \
 630                .gate_flags     = gf,                           \
 631                .child          = ch,                           \
 632        }
 633
 634#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
 635        {                                                       \
 636                .id             = _id,                          \
 637                .branch_type    = branch_fraction_divider,      \
 638                .name           = cname,                        \
 639                .parent_names   = (const char *[]){ pname },    \
 640                .num_parents    = 1,                            \
 641                .flags          = f,                            \
 642                .muxdiv_offset  = mo,                           \
 643                .div_shift      = 16,                           \
 644                .div_width      = 16,                           \
 645                .div_flags      = df,                           \
 646                .gate_offset    = -1,                           \
 647                .child          = ch,                           \
 648        }
 649
 650#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,     \
 651                         ds, dw, df)                            \
 652        {                                                       \
 653                .id             = _id,                          \
 654                .branch_type    = branch_ddrclk,                \
 655                .name           = cname,                        \
 656                .parent_names   = pnames,                       \
 657                .num_parents    = ARRAY_SIZE(pnames),           \
 658                .flags          = f,                            \
 659                .muxdiv_offset  = mo,                           \
 660                .mux_shift      = ms,                           \
 661                .mux_width      = mw,                           \
 662                .div_shift      = ds,                           \
 663                .div_width      = dw,                           \
 664                .div_flags      = df,                           \
 665                .gate_offset    = -1,                           \
 666        }
 667
 668#define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
 669        {                                                       \
 670                .id             = _id,                          \
 671                .branch_type    = branch_mux,                   \
 672                .name           = cname,                        \
 673                .parent_names   = pnames,                       \
 674                .num_parents    = ARRAY_SIZE(pnames),           \
 675                .flags          = f,                            \
 676                .muxdiv_offset  = o,                            \
 677                .mux_shift      = s,                            \
 678                .mux_width      = w,                            \
 679                .mux_flags      = mf,                           \
 680                .gate_offset    = -1,                           \
 681        }
 682
 683#define MUXGRF(_id, cname, pnames, f, o, s, w, mf)              \
 684        {                                                       \
 685                .id             = _id,                          \
 686                .branch_type    = branch_muxgrf,                \
 687                .name           = cname,                        \
 688                .parent_names   = pnames,                       \
 689                .num_parents    = ARRAY_SIZE(pnames),           \
 690                .flags          = f,                            \
 691                .muxdiv_offset  = o,                            \
 692                .mux_shift      = s,                            \
 693                .mux_width      = w,                            \
 694                .mux_flags      = mf,                           \
 695                .gate_offset    = -1,                           \
 696        }
 697
 698#define DIV(_id, cname, pname, f, o, s, w, df)                  \
 699        {                                                       \
 700                .id             = _id,                          \
 701                .branch_type    = branch_divider,               \
 702                .name           = cname,                        \
 703                .parent_names   = (const char *[]){ pname },    \
 704                .num_parents    = 1,                            \
 705                .flags          = f,                            \
 706                .muxdiv_offset  = o,                            \
 707                .div_shift      = s,                            \
 708                .div_width      = w,                            \
 709                .div_flags      = df,                           \
 710                .gate_offset    = -1,                           \
 711        }
 712
 713#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
 714        {                                                       \
 715                .id             = _id,                          \
 716                .branch_type    = branch_divider,               \
 717                .name           = cname,                        \
 718                .parent_names   = (const char *[]){ pname },    \
 719                .num_parents    = 1,                            \
 720                .flags          = f,                            \
 721                .muxdiv_offset  = o,                            \
 722                .div_shift      = s,                            \
 723                .div_width      = w,                            \
 724                .div_flags      = df,                           \
 725                .div_table      = dt,                           \
 726        }
 727
 728#define GATE(_id, cname, pname, f, o, b, gf)                    \
 729        {                                                       \
 730                .id             = _id,                          \
 731                .branch_type    = branch_gate,                  \
 732                .name           = cname,                        \
 733                .parent_names   = (const char *[]){ pname },    \
 734                .num_parents    = 1,                            \
 735                .flags          = f,                            \
 736                .gate_offset    = o,                            \
 737                .gate_shift     = b,                            \
 738                .gate_flags     = gf,                           \
 739        }
 740
 741#define MMC(_id, cname, pname, offset, shift)                   \
 742        {                                                       \
 743                .id             = _id,                          \
 744                .branch_type    = branch_mmc,                   \
 745                .name           = cname,                        \
 746                .parent_names   = (const char *[]){ pname },    \
 747                .num_parents    = 1,                            \
 748                .muxdiv_offset  = offset,                       \
 749                .div_shift      = shift,                        \
 750        }
 751
 752#define INVERTER(_id, cname, pname, io, is, if)                 \
 753        {                                                       \
 754                .id             = _id,                          \
 755                .branch_type    = branch_inverter,              \
 756                .name           = cname,                        \
 757                .parent_names   = (const char *[]){ pname },    \
 758                .num_parents    = 1,                            \
 759                .muxdiv_offset  = io,                           \
 760                .div_shift      = is,                           \
 761                .div_flags      = if,                           \
 762        }
 763
 764#define FACTOR(_id, cname, pname,  f, fm, fd)                   \
 765        {                                                       \
 766                .id             = _id,                          \
 767                .branch_type    = branch_factor,                \
 768                .name           = cname,                        \
 769                .parent_names   = (const char *[]){ pname },    \
 770                .num_parents    = 1,                            \
 771                .flags          = f,                            \
 772                .div_shift      = fm,                           \
 773                .div_width      = fd,                           \
 774        }
 775
 776#define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
 777        {                                                       \
 778                .id             = _id,                          \
 779                .branch_type    = branch_factor,                \
 780                .name           = cname,                        \
 781                .parent_names   = (const char *[]){ pname },    \
 782                .num_parents    = 1,                            \
 783                .flags          = f,                            \
 784                .div_shift      = fm,                           \
 785                .div_width      = fd,                           \
 786                .gate_offset    = go,                           \
 787                .gate_shift     = gb,                           \
 788                .gate_flags     = gf,                           \
 789        }
 790
 791#define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
 792                          df, go, gs, gf)                               \
 793        {                                                       \
 794                .id             = _id,                          \
 795                .branch_type    = branch_half_divider,          \
 796                .name           = cname,                        \
 797                .parent_names   = pnames,                       \
 798                .num_parents    = ARRAY_SIZE(pnames),           \
 799                .flags          = f,                            \
 800                .muxdiv_offset  = mo,                           \
 801                .mux_shift      = ms,                           \
 802                .mux_width      = mw,                           \
 803                .mux_flags      = mf,                           \
 804                .div_shift      = ds,                           \
 805                .div_width      = dw,                           \
 806                .div_flags      = df,                           \
 807                .gate_offset    = go,                           \
 808                .gate_shift     = gs,                           \
 809                .gate_flags     = gf,                           \
 810        }
 811
 812#define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \
 813                                 ds, dw, df)                            \
 814        {                                                       \
 815                .id             = _id,                          \
 816                .branch_type    = branch_half_divider,          \
 817                .name           = cname,                        \
 818                .parent_names   = pnames,                       \
 819                .num_parents    = ARRAY_SIZE(pnames),           \
 820                .flags          = f,                            \
 821                .muxdiv_offset  = mo,                           \
 822                .mux_shift      = ms,                           \
 823                .mux_width      = mw,                           \
 824                .mux_flags      = mf,                           \
 825                .div_shift      = ds,                           \
 826                .div_width      = dw,                           \
 827                .div_flags      = df,                           \
 828                .gate_offset    = -1,                           \
 829        }
 830
 831#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df,   \
 832                        go, gs, gf)                             \
 833        {                                                       \
 834                .id             = _id,                          \
 835                .branch_type    = branch_half_divider,          \
 836                .name           = cname,                        \
 837                .parent_names   = (const char *[]){ pname },    \
 838                .num_parents    = 1,                            \
 839                .flags          = f,                            \
 840                .muxdiv_offset  = mo,                           \
 841                .div_shift      = ds,                           \
 842                .div_width      = dw,                           \
 843                .div_flags      = df,                           \
 844                .gate_offset    = go,                           \
 845                .gate_shift     = gs,                           \
 846                .gate_flags     = gf,                           \
 847        }
 848
 849#define DIV_HALF(_id, cname, pname, f, o, s, w, df)                     \
 850        {                                                       \
 851                .id             = _id,                          \
 852                .branch_type    = branch_half_divider,          \
 853                .name           = cname,                        \
 854                .parent_names   = (const char *[]){ pname },    \
 855                .num_parents    = 1,                            \
 856                .flags          = f,                            \
 857                .muxdiv_offset  = o,                            \
 858                .div_shift      = s,                            \
 859                .div_width      = w,                            \
 860                .div_flags      = df,                           \
 861                .gate_offset    = -1,                           \
 862        }
 863
 864/* SGRF clocks are only accessible from secure mode, so not controllable */
 865#define SGRF_GATE(_id, cname, pname)                            \
 866                FACTOR(_id, cname, pname, 0, 1, 1)
 867
 868struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
 869                        void __iomem *base, unsigned long nr_clks);
 870void rockchip_clk_of_add_provider(struct device_node *np,
 871                                struct rockchip_clk_provider *ctx);
 872void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
 873                             struct clk *clk, unsigned int id);
 874void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 875                                    struct rockchip_clk_branch *list,
 876                                    unsigned int nr_clk);
 877void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
 878                                struct rockchip_pll_clock *pll_list,
 879                                unsigned int nr_pll, int grf_lock_offset);
 880void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 881                        unsigned int lookup_id, const char *name,
 882                        const char *const *parent_names, u8 num_parents,
 883                        const struct rockchip_cpuclk_reg_data *reg_data,
 884                        const struct rockchip_cpuclk_rate_table *rates,
 885                        int nrates);
 886void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
 887void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
 888                                        unsigned int reg, void (*cb)(void));
 889
 890#define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
 891
 892struct clk *rockchip_clk_register_halfdiv(const char *name,
 893                                          const char *const *parent_names,
 894                                          u8 num_parents, void __iomem *base,
 895                                          int muxdiv_offset, u8 mux_shift,
 896                                          u8 mux_width, u8 mux_flags,
 897                                          u8 div_shift, u8 div_width,
 898                                          u8 div_flags, int gate_offset,
 899                                          u8 gate_shift, u8 gate_flags,
 900                                          unsigned long flags,
 901                                          spinlock_t *lock);
 902
 903#ifdef CONFIG_RESET_CONTROLLER
 904void rockchip_register_softrst(struct device_node *np,
 905                               unsigned int num_regs,
 906                               void __iomem *base, u8 flags);
 907#else
 908static inline void rockchip_register_softrst(struct device_node *np,
 909                               unsigned int num_regs,
 910                               void __iomem *base, u8 flags)
 911{
 912}
 913#endif
 914
 915#endif
 916