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