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
 191enum rockchip_pll_type {
 192        pll_rk3036,
 193        pll_rk3066,
 194        pll_rk3328,
 195        pll_rk3399,
 196};
 197
 198#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
 199                        _postdiv2, _dsmpd, _frac)               \
 200{                                                               \
 201        .rate   = _rate##U,                                     \
 202        .fbdiv = _fbdiv,                                        \
 203        .postdiv1 = _postdiv1,                                  \
 204        .refdiv = _refdiv,                                      \
 205        .postdiv2 = _postdiv2,                                  \
 206        .dsmpd = _dsmpd,                                        \
 207        .frac = _frac,                                          \
 208}
 209
 210#define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
 211{                                               \
 212        .rate   = _rate##U,                     \
 213        .nr = _nr,                              \
 214        .nf = _nf,                              \
 215        .no = _no,                              \
 216        .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
 217}
 218
 219#define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
 220{                                                               \
 221        .rate   = _rate##U,                                     \
 222        .nr = _nr,                                              \
 223        .nf = _nf,                                              \
 224        .no = _no,                                              \
 225        .nb = _nb,                                              \
 226}
 227
 228/**
 229 * struct rockchip_clk_provider - information about clock provider
 230 * @reg_base: virtual address for the register base.
 231 * @clk_data: holds clock related data like clk* and number of clocks.
 232 * @cru_node: device-node of the clock-provider
 233 * @grf: regmap of the general-register-files syscon
 234 * @lock: maintains exclusion between callbacks for a given clock-provider.
 235 */
 236struct rockchip_clk_provider {
 237        void __iomem *reg_base;
 238        struct clk_onecell_data clk_data;
 239        struct device_node *cru_node;
 240        struct regmap *grf;
 241        spinlock_t lock;
 242};
 243
 244struct rockchip_pll_rate_table {
 245        unsigned long rate;
 246        unsigned int nr;
 247        unsigned int nf;
 248        unsigned int no;
 249        unsigned int nb;
 250        /* for RK3036/RK3399 */
 251        unsigned int fbdiv;
 252        unsigned int postdiv1;
 253        unsigned int refdiv;
 254        unsigned int postdiv2;
 255        unsigned int dsmpd;
 256        unsigned int frac;
 257};
 258
 259/**
 260 * struct rockchip_pll_clock - information about pll clock
 261 * @id: platform specific id of the clock.
 262 * @name: name of this pll clock.
 263 * @parent_names: name of the parent clock.
 264 * @num_parents: number of parents
 265 * @flags: optional flags for basic clock.
 266 * @con_offset: offset of the register for configuring the PLL.
 267 * @mode_offset: offset of the register for configuring the PLL-mode.
 268 * @mode_shift: offset inside the mode-register for the mode of this pll.
 269 * @lock_shift: offset inside the lock register for the lock status.
 270 * @type: Type of PLL to be registered.
 271 * @pll_flags: hardware-specific flags
 272 * @rate_table: Table of usable pll rates
 273 *
 274 * Flags:
 275 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
 276 *      rate_table parameters and ajust them if necessary.
 277 */
 278struct rockchip_pll_clock {
 279        unsigned int            id;
 280        const char              *name;
 281        const char              *const *parent_names;
 282        u8                      num_parents;
 283        unsigned long           flags;
 284        int                     con_offset;
 285        int                     mode_offset;
 286        int                     mode_shift;
 287        int                     lock_shift;
 288        enum rockchip_pll_type  type;
 289        u8                      pll_flags;
 290        struct rockchip_pll_rate_table *rate_table;
 291};
 292
 293#define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
 294
 295#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
 296                _lshift, _pflags, _rtable)                              \
 297        {                                                               \
 298                .id             = _id,                                  \
 299                .type           = _type,                                \
 300                .name           = _name,                                \
 301                .parent_names   = _pnames,                              \
 302                .num_parents    = ARRAY_SIZE(_pnames),                  \
 303                .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
 304                .con_offset     = _con,                                 \
 305                .mode_offset    = _mode,                                \
 306                .mode_shift     = _mshift,                              \
 307                .lock_shift     = _lshift,                              \
 308                .pll_flags      = _pflags,                              \
 309                .rate_table     = _rtable,                              \
 310        }
 311
 312struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
 313                enum rockchip_pll_type pll_type,
 314                const char *name, const char *const *parent_names,
 315                u8 num_parents, int con_offset, int grf_lock_offset,
 316                int lock_shift, int mode_offset, int mode_shift,
 317                struct rockchip_pll_rate_table *rate_table,
 318                unsigned long flags, u8 clk_pll_flags);
 319
 320struct rockchip_cpuclk_clksel {
 321        int reg;
 322        u32 val;
 323};
 324
 325#define ROCKCHIP_CPUCLK_NUM_DIVIDERS    2
 326struct rockchip_cpuclk_rate_table {
 327        unsigned long prate;
 328        struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
 329};
 330
 331/**
 332 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
 333 * @core_reg:           register offset of the core settings register
 334 * @div_core_shift:     core divider offset used to divide the pll value
 335 * @div_core_mask:      core divider mask
 336 * @mux_core_alt:       mux value to select alternate parent
 337 * @mux_core_main:      mux value to select main parent of core
 338 * @mux_core_shift:     offset of the core multiplexer
 339 * @mux_core_mask:      core multiplexer mask
 340 */
 341struct rockchip_cpuclk_reg_data {
 342        int             core_reg;
 343        u8              div_core_shift;
 344        u32             div_core_mask;
 345        u8              mux_core_alt;
 346        u8              mux_core_main;
 347        u8              mux_core_shift;
 348        u32             mux_core_mask;
 349};
 350
 351struct clk *rockchip_clk_register_cpuclk(const char *name,
 352                        const char *const *parent_names, u8 num_parents,
 353                        const struct rockchip_cpuclk_reg_data *reg_data,
 354                        const struct rockchip_cpuclk_rate_table *rates,
 355                        int nrates, void __iomem *reg_base, spinlock_t *lock);
 356
 357struct clk *rockchip_clk_register_mmc(const char *name,
 358                                const char *const *parent_names, u8 num_parents,
 359                                void __iomem *reg, int shift);
 360
 361/*
 362 * DDRCLK flags, including method of setting the rate
 363 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
 364 */
 365#define ROCKCHIP_DDRCLK_SIP             BIT(0)
 366
 367struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
 368                                         const char *const *parent_names,
 369                                         u8 num_parents, int mux_offset,
 370                                         int mux_shift, int mux_width,
 371                                         int div_shift, int div_width,
 372                                         int ddr_flags, void __iomem *reg_base,
 373                                         spinlock_t *lock);
 374
 375#define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
 376
 377struct clk *rockchip_clk_register_inverter(const char *name,
 378                                const char *const *parent_names, u8 num_parents,
 379                                void __iomem *reg, int shift, int flags,
 380                                spinlock_t *lock);
 381
 382struct clk *rockchip_clk_register_muxgrf(const char *name,
 383                                const char *const *parent_names, u8 num_parents,
 384                                int flags, struct regmap *grf, int reg,
 385                                int shift, int width, int mux_flags);
 386
 387#define PNAME(x) static const char *const x[] __initconst
 388
 389enum rockchip_clk_branch_type {
 390        branch_composite,
 391        branch_mux,
 392        branch_muxgrf,
 393        branch_divider,
 394        branch_fraction_divider,
 395        branch_gate,
 396        branch_mmc,
 397        branch_inverter,
 398        branch_factor,
 399        branch_ddrclk,
 400        branch_half_divider,
 401};
 402
 403struct rockchip_clk_branch {
 404        unsigned int                    id;
 405        enum rockchip_clk_branch_type   branch_type;
 406        const char                      *name;
 407        const char                      *const *parent_names;
 408        u8                              num_parents;
 409        unsigned long                   flags;
 410        int                             muxdiv_offset;
 411        u8                              mux_shift;
 412        u8                              mux_width;
 413        u8                              mux_flags;
 414        int                             div_offset;
 415        u8                              div_shift;
 416        u8                              div_width;
 417        u8                              div_flags;
 418        struct clk_div_table            *div_table;
 419        int                             gate_offset;
 420        u8                              gate_shift;
 421        u8                              gate_flags;
 422        struct rockchip_clk_branch      *child;
 423};
 424
 425#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
 426                  df, go, gs, gf)                               \
 427        {                                                       \
 428                .id             = _id,                          \
 429                .branch_type    = branch_composite,             \
 430                .name           = cname,                        \
 431                .parent_names   = pnames,                       \
 432                .num_parents    = ARRAY_SIZE(pnames),           \
 433                .flags          = f,                            \
 434                .muxdiv_offset  = mo,                           \
 435                .mux_shift      = ms,                           \
 436                .mux_width      = mw,                           \
 437                .mux_flags      = mf,                           \
 438                .div_shift      = ds,                           \
 439                .div_width      = dw,                           \
 440                .div_flags      = df,                           \
 441                .gate_offset    = go,                           \
 442                .gate_shift     = gs,                           \
 443                .gate_flags     = gf,                           \
 444        }
 445
 446#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
 447                             mf, do, ds, dw, df, go, gs, gf)    \
 448        {                                                       \
 449                .id             = _id,                          \
 450                .branch_type    = branch_composite,             \
 451                .name           = cname,                        \
 452                .parent_names   = pnames,                       \
 453                .num_parents    = ARRAY_SIZE(pnames),           \
 454                .flags          = f,                            \
 455                .muxdiv_offset  = mo,                           \
 456                .mux_shift      = ms,                           \
 457                .mux_width      = mw,                           \
 458                .mux_flags      = mf,                           \
 459                .div_offset     = do,                           \
 460                .div_shift      = ds,                           \
 461                .div_width      = dw,                           \
 462                .div_flags      = df,                           \
 463                .gate_offset    = go,                           \
 464                .gate_shift     = gs,                           \
 465                .gate_flags     = gf,                           \
 466        }
 467
 468#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
 469                        go, gs, gf)                             \
 470        {                                                       \
 471                .id             = _id,                          \
 472                .branch_type    = branch_composite,             \
 473                .name           = cname,                        \
 474                .parent_names   = (const char *[]){ pname },    \
 475                .num_parents    = 1,                            \
 476                .flags          = f,                            \
 477                .muxdiv_offset  = mo,                           \
 478                .div_shift      = ds,                           \
 479                .div_width      = dw,                           \
 480                .div_flags      = df,                           \
 481                .gate_offset    = go,                           \
 482                .gate_shift     = gs,                           \
 483                .gate_flags     = gf,                           \
 484        }
 485
 486#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
 487                               df, dt, go, gs, gf)              \
 488        {                                                       \
 489                .id             = _id,                          \
 490                .branch_type    = branch_composite,             \
 491                .name           = cname,                        \
 492                .parent_names   = (const char *[]){ pname },    \
 493                .num_parents    = 1,                            \
 494                .flags          = f,                            \
 495                .muxdiv_offset  = mo,                           \
 496                .div_shift      = ds,                           \
 497                .div_width      = dw,                           \
 498                .div_flags      = df,                           \
 499                .div_table      = dt,                           \
 500                .gate_offset    = go,                           \
 501                .gate_shift     = gs,                           \
 502                .gate_flags     = gf,                           \
 503        }
 504
 505#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
 506                        go, gs, gf)                             \
 507        {                                                       \
 508                .id             = _id,                          \
 509                .branch_type    = branch_composite,             \
 510                .name           = cname,                        \
 511                .parent_names   = pnames,                       \
 512                .num_parents    = ARRAY_SIZE(pnames),           \
 513                .flags          = f,                            \
 514                .muxdiv_offset  = mo,                           \
 515                .mux_shift      = ms,                           \
 516                .mux_width      = mw,                           \
 517                .mux_flags      = mf,                           \
 518                .gate_offset    = go,                           \
 519                .gate_shift     = gs,                           \
 520                .gate_flags     = gf,                           \
 521        }
 522
 523#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
 524                         ds, dw, df)                            \
 525        {                                                       \
 526                .id             = _id,                          \
 527                .branch_type    = branch_composite,             \
 528                .name           = cname,                        \
 529                .parent_names   = pnames,                       \
 530                .num_parents    = ARRAY_SIZE(pnames),           \
 531                .flags          = f,                            \
 532                .muxdiv_offset  = mo,                           \
 533                .mux_shift      = ms,                           \
 534                .mux_width      = mw,                           \
 535                .mux_flags      = mf,                           \
 536                .div_shift      = ds,                           \
 537                .div_width      = dw,                           \
 538                .div_flags      = df,                           \
 539                .gate_offset    = -1,                           \
 540        }
 541
 542#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
 543                                mw, mf, ds, dw, df, dt)         \
 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                .div_shift      = ds,                           \
 556                .div_width      = dw,                           \
 557                .div_flags      = df,                           \
 558                .div_table      = dt,                           \
 559                .gate_offset    = -1,                           \
 560        }
 561
 562#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
 563        {                                                       \
 564                .id             = _id,                          \
 565                .branch_type    = branch_fraction_divider,      \
 566                .name           = cname,                        \
 567                .parent_names   = (const char *[]){ pname },    \
 568                .num_parents    = 1,                            \
 569                .flags          = f,                            \
 570                .muxdiv_offset  = mo,                           \
 571                .div_shift      = 16,                           \
 572                .div_width      = 16,                           \
 573                .div_flags      = df,                           \
 574                .gate_offset    = go,                           \
 575                .gate_shift     = gs,                           \
 576                .gate_flags     = gf,                           \
 577        }
 578
 579#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
 580        {                                                       \
 581                .id             = _id,                          \
 582                .branch_type    = branch_fraction_divider,      \
 583                .name           = cname,                        \
 584                .parent_names   = (const char *[]){ pname },    \
 585                .num_parents    = 1,                            \
 586                .flags          = f,                            \
 587                .muxdiv_offset  = mo,                           \
 588                .div_shift      = 16,                           \
 589                .div_width      = 16,                           \
 590                .div_flags      = df,                           \
 591                .gate_offset    = go,                           \
 592                .gate_shift     = gs,                           \
 593                .gate_flags     = gf,                           \
 594                .child          = ch,                           \
 595        }
 596
 597#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
 598        {                                                       \
 599                .id             = _id,                          \
 600                .branch_type    = branch_fraction_divider,      \
 601                .name           = cname,                        \
 602                .parent_names   = (const char *[]){ pname },    \
 603                .num_parents    = 1,                            \
 604                .flags          = f,                            \
 605                .muxdiv_offset  = mo,                           \
 606                .div_shift      = 16,                           \
 607                .div_width      = 16,                           \
 608                .div_flags      = df,                           \
 609                .gate_offset    = -1,                           \
 610                .child          = ch,                           \
 611        }
 612
 613#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,     \
 614                         ds, dw, df)                            \
 615        {                                                       \
 616                .id             = _id,                          \
 617                .branch_type    = branch_ddrclk,                \
 618                .name           = cname,                        \
 619                .parent_names   = pnames,                       \
 620                .num_parents    = ARRAY_SIZE(pnames),           \
 621                .flags          = f,                            \
 622                .muxdiv_offset  = mo,                           \
 623                .mux_shift      = ms,                           \
 624                .mux_width      = mw,                           \
 625                .div_shift      = ds,                           \
 626                .div_width      = dw,                           \
 627                .div_flags      = df,                           \
 628                .gate_offset    = -1,                           \
 629        }
 630
 631#define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
 632        {                                                       \
 633                .id             = _id,                          \
 634                .branch_type    = branch_mux,                   \
 635                .name           = cname,                        \
 636                .parent_names   = pnames,                       \
 637                .num_parents    = ARRAY_SIZE(pnames),           \
 638                .flags          = f,                            \
 639                .muxdiv_offset  = o,                            \
 640                .mux_shift      = s,                            \
 641                .mux_width      = w,                            \
 642                .mux_flags      = mf,                           \
 643                .gate_offset    = -1,                           \
 644        }
 645
 646#define MUXGRF(_id, cname, pnames, f, o, s, w, mf)              \
 647        {                                                       \
 648                .id             = _id,                          \
 649                .branch_type    = branch_muxgrf,                \
 650                .name           = cname,                        \
 651                .parent_names   = pnames,                       \
 652                .num_parents    = ARRAY_SIZE(pnames),           \
 653                .flags          = f,                            \
 654                .muxdiv_offset  = o,                            \
 655                .mux_shift      = s,                            \
 656                .mux_width      = w,                            \
 657                .mux_flags      = mf,                           \
 658                .gate_offset    = -1,                           \
 659        }
 660
 661#define DIV(_id, cname, pname, f, o, s, w, df)                  \
 662        {                                                       \
 663                .id             = _id,                          \
 664                .branch_type    = branch_divider,               \
 665                .name           = cname,                        \
 666                .parent_names   = (const char *[]){ pname },    \
 667                .num_parents    = 1,                            \
 668                .flags          = f,                            \
 669                .muxdiv_offset  = o,                            \
 670                .div_shift      = s,                            \
 671                .div_width      = w,                            \
 672                .div_flags      = df,                           \
 673                .gate_offset    = -1,                           \
 674        }
 675
 676#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
 677        {                                                       \
 678                .id             = _id,                          \
 679                .branch_type    = branch_divider,               \
 680                .name           = cname,                        \
 681                .parent_names   = (const char *[]){ pname },    \
 682                .num_parents    = 1,                            \
 683                .flags          = f,                            \
 684                .muxdiv_offset  = o,                            \
 685                .div_shift      = s,                            \
 686                .div_width      = w,                            \
 687                .div_flags      = df,                           \
 688                .div_table      = dt,                           \
 689        }
 690
 691#define GATE(_id, cname, pname, f, o, b, gf)                    \
 692        {                                                       \
 693                .id             = _id,                          \
 694                .branch_type    = branch_gate,                  \
 695                .name           = cname,                        \
 696                .parent_names   = (const char *[]){ pname },    \
 697                .num_parents    = 1,                            \
 698                .flags          = f,                            \
 699                .gate_offset    = o,                            \
 700                .gate_shift     = b,                            \
 701                .gate_flags     = gf,                           \
 702        }
 703
 704#define MMC(_id, cname, pname, offset, shift)                   \
 705        {                                                       \
 706                .id             = _id,                          \
 707                .branch_type    = branch_mmc,                   \
 708                .name           = cname,                        \
 709                .parent_names   = (const char *[]){ pname },    \
 710                .num_parents    = 1,                            \
 711                .muxdiv_offset  = offset,                       \
 712                .div_shift      = shift,                        \
 713        }
 714
 715#define INVERTER(_id, cname, pname, io, is, if)                 \
 716        {                                                       \
 717                .id             = _id,                          \
 718                .branch_type    = branch_inverter,              \
 719                .name           = cname,                        \
 720                .parent_names   = (const char *[]){ pname },    \
 721                .num_parents    = 1,                            \
 722                .muxdiv_offset  = io,                           \
 723                .div_shift      = is,                           \
 724                .div_flags      = if,                           \
 725        }
 726
 727#define FACTOR(_id, cname, pname,  f, fm, fd)                   \
 728        {                                                       \
 729                .id             = _id,                          \
 730                .branch_type    = branch_factor,                \
 731                .name           = cname,                        \
 732                .parent_names   = (const char *[]){ pname },    \
 733                .num_parents    = 1,                            \
 734                .flags          = f,                            \
 735                .div_shift      = fm,                           \
 736                .div_width      = fd,                           \
 737        }
 738
 739#define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
 740        {                                                       \
 741                .id             = _id,                          \
 742                .branch_type    = branch_factor,                \
 743                .name           = cname,                        \
 744                .parent_names   = (const char *[]){ pname },    \
 745                .num_parents    = 1,                            \
 746                .flags          = f,                            \
 747                .div_shift      = fm,                           \
 748                .div_width      = fd,                           \
 749                .gate_offset    = go,                           \
 750                .gate_shift     = gb,                           \
 751                .gate_flags     = gf,                           \
 752        }
 753
 754#define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
 755                          df, go, gs, gf)                               \
 756        {                                                       \
 757                .id             = _id,                          \
 758                .branch_type    = branch_half_divider,          \
 759                .name           = cname,                        \
 760                .parent_names   = pnames,                       \
 761                .num_parents    = ARRAY_SIZE(pnames),           \
 762                .flags          = f,                            \
 763                .muxdiv_offset  = mo,                           \
 764                .mux_shift      = ms,                           \
 765                .mux_width      = mw,                           \
 766                .mux_flags      = mf,                           \
 767                .div_shift      = ds,                           \
 768                .div_width      = dw,                           \
 769                .div_flags      = df,                           \
 770                .gate_offset    = go,                           \
 771                .gate_shift     = gs,                           \
 772                .gate_flags     = gf,                           \
 773        }
 774
 775#define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \
 776                                 ds, dw, df)                            \
 777        {                                                       \
 778                .id             = _id,                          \
 779                .branch_type    = branch_half_divider,          \
 780                .name           = cname,                        \
 781                .parent_names   = pnames,                       \
 782                .num_parents    = ARRAY_SIZE(pnames),           \
 783                .flags          = f,                            \
 784                .muxdiv_offset  = mo,                           \
 785                .mux_shift      = ms,                           \
 786                .mux_width      = mw,                           \
 787                .mux_flags      = mf,                           \
 788                .div_shift      = ds,                           \
 789                .div_width      = dw,                           \
 790                .div_flags      = df,                           \
 791                .gate_offset    = -1,                           \
 792        }
 793
 794#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df,   \
 795                        go, gs, gf)                             \
 796        {                                                       \
 797                .id             = _id,                          \
 798                .branch_type    = branch_half_divider,          \
 799                .name           = cname,                        \
 800                .parent_names   = (const char *[]){ pname },    \
 801                .num_parents    = 1,                            \
 802                .flags          = f,                            \
 803                .muxdiv_offset  = mo,                           \
 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 DIV_HALF(_id, cname, pname, f, o, s, w, df)                     \
 813        {                                                       \
 814                .id             = _id,                          \
 815                .branch_type    = branch_half_divider,          \
 816                .name           = cname,                        \
 817                .parent_names   = (const char *[]){ pname },    \
 818                .num_parents    = 1,                            \
 819                .flags          = f,                            \
 820                .muxdiv_offset  = o,                            \
 821                .div_shift      = s,                            \
 822                .div_width      = w,                            \
 823                .div_flags      = df,                           \
 824                .gate_offset    = -1,                           \
 825        }
 826
 827/* SGRF clocks are only accessible from secure mode, so not controllable */
 828#define SGRF_GATE(_id, cname, pname)                            \
 829                FACTOR(_id, cname, pname, 0, 1, 1)
 830
 831struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
 832                        void __iomem *base, unsigned long nr_clks);
 833void rockchip_clk_of_add_provider(struct device_node *np,
 834                                struct rockchip_clk_provider *ctx);
 835void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
 836                             struct clk *clk, unsigned int id);
 837void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 838                                    struct rockchip_clk_branch *list,
 839                                    unsigned int nr_clk);
 840void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
 841                                struct rockchip_pll_clock *pll_list,
 842                                unsigned int nr_pll, int grf_lock_offset);
 843void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 844                        unsigned int lookup_id, const char *name,
 845                        const char *const *parent_names, u8 num_parents,
 846                        const struct rockchip_cpuclk_reg_data *reg_data,
 847                        const struct rockchip_cpuclk_rate_table *rates,
 848                        int nrates);
 849void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
 850void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
 851                                        unsigned int reg, void (*cb)(void));
 852
 853#define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
 854
 855struct clk *rockchip_clk_register_halfdiv(const char *name,
 856                                          const char *const *parent_names,
 857                                          u8 num_parents, void __iomem *base,
 858                                          int muxdiv_offset, u8 mux_shift,
 859                                          u8 mux_width, u8 mux_flags,
 860                                          u8 div_shift, u8 div_width,
 861                                          u8 div_flags, int gate_offset,
 862                                          u8 gate_shift, u8 gate_flags,
 863                                          unsigned long flags,
 864                                          spinlock_t *lock);
 865
 866#ifdef CONFIG_RESET_CONTROLLER
 867void rockchip_register_softrst(struct device_node *np,
 868                               unsigned int num_regs,
 869                               void __iomem *base, u8 flags);
 870#else
 871static inline void rockchip_register_softrst(struct device_node *np,
 872                               unsigned int num_regs,
 873                               void __iomem *base, u8 flags)
 874{
 875}
 876#endif
 877
 878#endif
 879