linux/drivers/clk/rockchip/clk.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2014 MundoReader S.L.
   3 * Author: Heiko Stuebner <heiko@sntech.de>
   4 *
   5 * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
   6 * Author: Xing Zheng <zhengxing@rock-chips.com>
   7 *
   8 * based on
   9 *
  10 * samsung/clk.h
  11 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  12 * Copyright (c) 2013 Linaro Ltd.
  13 * Author: Thomas Abraham <thomas.ab@samsung.com>
  14 *
  15 * This program is free software; you can redistribute it and/or modify
  16 * it under the terms of the GNU General Public License as published by
  17 * the Free Software Foundation; either version 2 of the License, or
  18 * (at your option) any later version.
  19 *
  20 * This program is distributed in the hope that it will be useful,
  21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 * GNU General Public License for more details.
  24 */
  25
  26#ifndef CLK_ROCKCHIP_CLK_H
  27#define CLK_ROCKCHIP_CLK_H
  28
  29#include <linux/io.h>
  30#include <linux/clk-provider.h>
  31
  32struct clk;
  33
  34#define HIWORD_UPDATE(val, mask, shift) \
  35                ((val) << (shift) | (mask) << ((shift) + 16))
  36
  37/* register positions shared by RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
  38#define RV1108_PLL_CON(x)               ((x) * 0x4)
  39#define RV1108_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
  40#define RV1108_CLKGATE_CON(x)           ((x) * 0x4 + 0x120)
  41#define RV1108_SOFTRST_CON(x)           ((x) * 0x4 + 0x180)
  42#define RV1108_GLB_SRST_FST             0x1c0
  43#define RV1108_GLB_SRST_SND             0x1c4
  44#define RV1108_MISC_CON                 0x1cc
  45#define RV1108_SDMMC_CON0               0x1d8
  46#define RV1108_SDMMC_CON1               0x1dc
  47#define RV1108_SDIO_CON0                0x1e0
  48#define RV1108_SDIO_CON1                0x1e4
  49#define RV1108_EMMC_CON0                0x1e8
  50#define RV1108_EMMC_CON1                0x1ec
  51
  52#define RK2928_PLL_CON(x)               ((x) * 0x4)
  53#define RK2928_MODE_CON         0x40
  54#define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
  55#define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
  56#define RK2928_GLB_SRST_FST             0x100
  57#define RK2928_GLB_SRST_SND             0x104
  58#define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
  59#define RK2928_MISC_CON         0x134
  60
  61#define RK3036_SDMMC_CON0               0x144
  62#define RK3036_SDMMC_CON1               0x148
  63#define RK3036_SDIO_CON0                0x14c
  64#define RK3036_SDIO_CON1                0x150
  65#define RK3036_EMMC_CON0                0x154
  66#define RK3036_EMMC_CON1                0x158
  67
  68#define RK3228_GLB_SRST_FST             0x1f0
  69#define RK3228_GLB_SRST_SND             0x1f4
  70#define RK3228_SDMMC_CON0               0x1c0
  71#define RK3228_SDMMC_CON1               0x1c4
  72#define RK3228_SDIO_CON0                0x1c8
  73#define RK3228_SDIO_CON1                0x1cc
  74#define RK3228_EMMC_CON0                0x1d8
  75#define RK3228_EMMC_CON1                0x1dc
  76
  77#define RK3288_PLL_CON(x)               RK2928_PLL_CON(x)
  78#define RK3288_MODE_CON                 0x50
  79#define RK3288_CLKSEL_CON(x)            ((x) * 0x4 + 0x60)
  80#define RK3288_CLKGATE_CON(x)           ((x) * 0x4 + 0x160)
  81#define RK3288_GLB_SRST_FST             0x1b0
  82#define RK3288_GLB_SRST_SND             0x1b4
  83#define RK3288_SOFTRST_CON(x)           ((x) * 0x4 + 0x1b8)
  84#define RK3288_MISC_CON                 0x1e8
  85#define RK3288_SDMMC_CON0               0x200
  86#define RK3288_SDMMC_CON1               0x204
  87#define RK3288_SDIO0_CON0               0x208
  88#define RK3288_SDIO0_CON1               0x20c
  89#define RK3288_SDIO1_CON0               0x210
  90#define RK3288_SDIO1_CON1               0x214
  91#define RK3288_EMMC_CON0                0x218
  92#define RK3288_EMMC_CON1                0x21c
  93
  94#define RK3328_PLL_CON(x)               RK2928_PLL_CON(x)
  95#define RK3328_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
  96#define RK3328_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
  97#define RK3328_GRFCLKSEL_CON(x)         ((x) * 0x4 + 0x100)
  98#define RK3328_GLB_SRST_FST             0x9c
  99#define RK3328_GLB_SRST_SND             0x98
 100#define RK3328_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
 101#define RK3328_MODE_CON                 0x80
 102#define RK3328_MISC_CON                 0x84
 103#define RK3328_SDMMC_CON0               0x380
 104#define RK3328_SDMMC_CON1               0x384
 105#define RK3328_SDIO_CON0                0x388
 106#define RK3328_SDIO_CON1                0x38c
 107#define RK3328_EMMC_CON0                0x390
 108#define RK3328_EMMC_CON1                0x394
 109#define RK3328_SDMMC_EXT_CON0           0x398
 110#define RK3328_SDMMC_EXT_CON1           0x39C
 111
 112#define RK3368_PLL_CON(x)               RK2928_PLL_CON(x)
 113#define RK3368_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 114#define RK3368_CLKGATE_CON(x)           ((x) * 0x4 + 0x200)
 115#define RK3368_GLB_SRST_FST             0x280
 116#define RK3368_GLB_SRST_SND             0x284
 117#define RK3368_SOFTRST_CON(x)           ((x) * 0x4 + 0x300)
 118#define RK3368_MISC_CON                 0x380
 119#define RK3368_SDMMC_CON0               0x400
 120#define RK3368_SDMMC_CON1               0x404
 121#define RK3368_SDIO0_CON0               0x408
 122#define RK3368_SDIO0_CON1               0x40c
 123#define RK3368_SDIO1_CON0               0x410
 124#define RK3368_SDIO1_CON1               0x414
 125#define RK3368_EMMC_CON0                0x418
 126#define RK3368_EMMC_CON1                0x41c
 127
 128#define RK3399_PLL_CON(x)               RK2928_PLL_CON(x)
 129#define RK3399_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
 130#define RK3399_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
 131#define RK3399_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
 132#define RK3399_GLB_SRST_FST             0x500
 133#define RK3399_GLB_SRST_SND             0x504
 134#define RK3399_GLB_CNT_TH               0x508
 135#define RK3399_MISC_CON                 0x50c
 136#define RK3399_RST_CON                  0x510
 137#define RK3399_RST_ST                   0x514
 138#define RK3399_SDMMC_CON0               0x580
 139#define RK3399_SDMMC_CON1               0x584
 140#define RK3399_SDIO_CON0                0x588
 141#define RK3399_SDIO_CON1                0x58c
 142
 143#define RK3399_PMU_PLL_CON(x)           RK2928_PLL_CON(x)
 144#define RK3399_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x80)
 145#define RK3399_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x100)
 146#define RK3399_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x110)
 147
 148enum rockchip_pll_type {
 149        pll_rk3036,
 150        pll_rk3066,
 151        pll_rk3328,
 152        pll_rk3399,
 153};
 154
 155#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,      \
 156                        _postdiv2, _dsmpd, _frac)               \
 157{                                                               \
 158        .rate   = _rate##U,                                     \
 159        .fbdiv = _fbdiv,                                        \
 160        .postdiv1 = _postdiv1,                                  \
 161        .refdiv = _refdiv,                                      \
 162        .postdiv2 = _postdiv2,                                  \
 163        .dsmpd = _dsmpd,                                        \
 164        .frac = _frac,                                          \
 165}
 166
 167#define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
 168{                                               \
 169        .rate   = _rate##U,                     \
 170        .nr = _nr,                              \
 171        .nf = _nf,                              \
 172        .no = _no,                              \
 173        .nb = ((_nf) < 2) ? 1 : (_nf) >> 1,     \
 174}
 175
 176#define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)           \
 177{                                                               \
 178        .rate   = _rate##U,                                     \
 179        .nr = _nr,                                              \
 180        .nf = _nf,                                              \
 181        .no = _no,                                              \
 182        .nb = _nb,                                              \
 183}
 184
 185/**
 186 * struct rockchip_clk_provider - information about clock provider
 187 * @reg_base: virtual address for the register base.
 188 * @clk_data: holds clock related data like clk* and number of clocks.
 189 * @cru_node: device-node of the clock-provider
 190 * @grf: regmap of the general-register-files syscon
 191 * @lock: maintains exclusion between callbacks for a given clock-provider.
 192 */
 193struct rockchip_clk_provider {
 194        void __iomem *reg_base;
 195        struct clk_onecell_data clk_data;
 196        struct device_node *cru_node;
 197        struct regmap *grf;
 198        spinlock_t lock;
 199};
 200
 201struct rockchip_pll_rate_table {
 202        unsigned long rate;
 203        unsigned int nr;
 204        unsigned int nf;
 205        unsigned int no;
 206        unsigned int nb;
 207        /* for RK3036/RK3399 */
 208        unsigned int fbdiv;
 209        unsigned int postdiv1;
 210        unsigned int refdiv;
 211        unsigned int postdiv2;
 212        unsigned int dsmpd;
 213        unsigned int frac;
 214};
 215
 216/**
 217 * struct rockchip_pll_clock - information about pll clock
 218 * @id: platform specific id of the clock.
 219 * @name: name of this pll clock.
 220 * @parent_names: name of the parent clock.
 221 * @num_parents: number of parents
 222 * @flags: optional flags for basic clock.
 223 * @con_offset: offset of the register for configuring the PLL.
 224 * @mode_offset: offset of the register for configuring the PLL-mode.
 225 * @mode_shift: offset inside the mode-register for the mode of this pll.
 226 * @lock_shift: offset inside the lock register for the lock status.
 227 * @type: Type of PLL to be registered.
 228 * @pll_flags: hardware-specific flags
 229 * @rate_table: Table of usable pll rates
 230 *
 231 * Flags:
 232 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
 233 *      rate_table parameters and ajust them if necessary.
 234 */
 235struct rockchip_pll_clock {
 236        unsigned int            id;
 237        const char              *name;
 238        const char              *const *parent_names;
 239        u8                      num_parents;
 240        unsigned long           flags;
 241        int                     con_offset;
 242        int                     mode_offset;
 243        int                     mode_shift;
 244        int                     lock_shift;
 245        enum rockchip_pll_type  type;
 246        u8                      pll_flags;
 247        struct rockchip_pll_rate_table *rate_table;
 248};
 249
 250#define ROCKCHIP_PLL_SYNC_RATE          BIT(0)
 251
 252#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
 253                _lshift, _pflags, _rtable)                              \
 254        {                                                               \
 255                .id             = _id,                                  \
 256                .type           = _type,                                \
 257                .name           = _name,                                \
 258                .parent_names   = _pnames,                              \
 259                .num_parents    = ARRAY_SIZE(_pnames),                  \
 260                .flags          = CLK_GET_RATE_NOCACHE | _flags,        \
 261                .con_offset     = _con,                                 \
 262                .mode_offset    = _mode,                                \
 263                .mode_shift     = _mshift,                              \
 264                .lock_shift     = _lshift,                              \
 265                .pll_flags      = _pflags,                              \
 266                .rate_table     = _rtable,                              \
 267        }
 268
 269struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
 270                enum rockchip_pll_type pll_type,
 271                const char *name, const char *const *parent_names,
 272                u8 num_parents, int con_offset, int grf_lock_offset,
 273                int lock_shift, int mode_offset, int mode_shift,
 274                struct rockchip_pll_rate_table *rate_table,
 275                unsigned long flags, u8 clk_pll_flags);
 276
 277struct rockchip_cpuclk_clksel {
 278        int reg;
 279        u32 val;
 280};
 281
 282#define ROCKCHIP_CPUCLK_NUM_DIVIDERS    2
 283struct rockchip_cpuclk_rate_table {
 284        unsigned long prate;
 285        struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
 286};
 287
 288/**
 289 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
 290 * @core_reg:           register offset of the core settings register
 291 * @div_core_shift:     core divider offset used to divide the pll value
 292 * @div_core_mask:      core divider mask
 293 * @mux_core_alt:       mux value to select alternate parent
 294 * @mux_core_main:      mux value to select main parent of core
 295 * @mux_core_shift:     offset of the core multiplexer
 296 * @mux_core_mask:      core multiplexer mask
 297 */
 298struct rockchip_cpuclk_reg_data {
 299        int             core_reg;
 300        u8              div_core_shift;
 301        u32             div_core_mask;
 302        u8              mux_core_alt;
 303        u8              mux_core_main;
 304        u8              mux_core_shift;
 305        u32             mux_core_mask;
 306};
 307
 308struct clk *rockchip_clk_register_cpuclk(const char *name,
 309                        const char *const *parent_names, u8 num_parents,
 310                        const struct rockchip_cpuclk_reg_data *reg_data,
 311                        const struct rockchip_cpuclk_rate_table *rates,
 312                        int nrates, void __iomem *reg_base, spinlock_t *lock);
 313
 314struct clk *rockchip_clk_register_mmc(const char *name,
 315                                const char *const *parent_names, u8 num_parents,
 316                                void __iomem *reg, int shift);
 317
 318/*
 319 * DDRCLK flags, including method of setting the rate
 320 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
 321 */
 322#define ROCKCHIP_DDRCLK_SIP             BIT(0)
 323
 324struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
 325                                         const char *const *parent_names,
 326                                         u8 num_parents, int mux_offset,
 327                                         int mux_shift, int mux_width,
 328                                         int div_shift, int div_width,
 329                                         int ddr_flags, void __iomem *reg_base,
 330                                         spinlock_t *lock);
 331
 332#define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
 333
 334struct clk *rockchip_clk_register_inverter(const char *name,
 335                                const char *const *parent_names, u8 num_parents,
 336                                void __iomem *reg, int shift, int flags,
 337                                spinlock_t *lock);
 338
 339struct clk *rockchip_clk_register_muxgrf(const char *name,
 340                                const char *const *parent_names, u8 num_parents,
 341                                int flags, struct regmap *grf, int reg,
 342                                int shift, int width, int mux_flags);
 343
 344#define PNAME(x) static const char *const x[] __initconst
 345
 346enum rockchip_clk_branch_type {
 347        branch_composite,
 348        branch_mux,
 349        branch_muxgrf,
 350        branch_divider,
 351        branch_fraction_divider,
 352        branch_gate,
 353        branch_mmc,
 354        branch_inverter,
 355        branch_factor,
 356        branch_ddrclk,
 357};
 358
 359struct rockchip_clk_branch {
 360        unsigned int                    id;
 361        enum rockchip_clk_branch_type   branch_type;
 362        const char                      *name;
 363        const char                      *const *parent_names;
 364        u8                              num_parents;
 365        unsigned long                   flags;
 366        int                             muxdiv_offset;
 367        u8                              mux_shift;
 368        u8                              mux_width;
 369        u8                              mux_flags;
 370        u8                              div_shift;
 371        u8                              div_width;
 372        u8                              div_flags;
 373        struct clk_div_table            *div_table;
 374        int                             gate_offset;
 375        u8                              gate_shift;
 376        u8                              gate_flags;
 377        struct rockchip_clk_branch      *child;
 378};
 379
 380#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
 381                  df, go, gs, gf)                               \
 382        {                                                       \
 383                .id             = _id,                          \
 384                .branch_type    = branch_composite,             \
 385                .name           = cname,                        \
 386                .parent_names   = pnames,                       \
 387                .num_parents    = ARRAY_SIZE(pnames),           \
 388                .flags          = f,                            \
 389                .muxdiv_offset  = mo,                           \
 390                .mux_shift      = ms,                           \
 391                .mux_width      = mw,                           \
 392                .mux_flags      = mf,                           \
 393                .div_shift      = ds,                           \
 394                .div_width      = dw,                           \
 395                .div_flags      = df,                           \
 396                .gate_offset    = go,                           \
 397                .gate_shift     = gs,                           \
 398                .gate_flags     = gf,                           \
 399        }
 400
 401#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
 402                        go, gs, gf)                             \
 403        {                                                       \
 404                .id             = _id,                          \
 405                .branch_type    = branch_composite,             \
 406                .name           = cname,                        \
 407                .parent_names   = (const char *[]){ pname },    \
 408                .num_parents    = 1,                            \
 409                .flags          = f,                            \
 410                .muxdiv_offset  = mo,                           \
 411                .div_shift      = ds,                           \
 412                .div_width      = dw,                           \
 413                .div_flags      = df,                           \
 414                .gate_offset    = go,                           \
 415                .gate_shift     = gs,                           \
 416                .gate_flags     = gf,                           \
 417        }
 418
 419#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
 420                               df, dt, go, gs, gf)              \
 421        {                                                       \
 422                .id             = _id,                          \
 423                .branch_type    = branch_composite,             \
 424                .name           = cname,                        \
 425                .parent_names   = (const char *[]){ pname },    \
 426                .num_parents    = 1,                            \
 427                .flags          = f,                            \
 428                .muxdiv_offset  = mo,                           \
 429                .div_shift      = ds,                           \
 430                .div_width      = dw,                           \
 431                .div_flags      = df,                           \
 432                .div_table      = dt,                           \
 433                .gate_offset    = go,                           \
 434                .gate_shift     = gs,                           \
 435                .gate_flags     = gf,                           \
 436        }
 437
 438#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
 439                        go, gs, gf)                             \
 440        {                                                       \
 441                .id             = _id,                          \
 442                .branch_type    = branch_composite,             \
 443                .name           = cname,                        \
 444                .parent_names   = pnames,                       \
 445                .num_parents    = ARRAY_SIZE(pnames),           \
 446                .flags          = f,                            \
 447                .muxdiv_offset  = mo,                           \
 448                .mux_shift      = ms,                           \
 449                .mux_width      = mw,                           \
 450                .mux_flags      = mf,                           \
 451                .gate_offset    = go,                           \
 452                .gate_shift     = gs,                           \
 453                .gate_flags     = gf,                           \
 454        }
 455
 456#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
 457                         ds, dw, df)                            \
 458        {                                                       \
 459                .id             = _id,                          \
 460                .branch_type    = branch_composite,             \
 461                .name           = cname,                        \
 462                .parent_names   = pnames,                       \
 463                .num_parents    = ARRAY_SIZE(pnames),           \
 464                .flags          = f,                            \
 465                .muxdiv_offset  = mo,                           \
 466                .mux_shift      = ms,                           \
 467                .mux_width      = mw,                           \
 468                .mux_flags      = mf,                           \
 469                .div_shift      = ds,                           \
 470                .div_width      = dw,                           \
 471                .div_flags      = df,                           \
 472                .gate_offset    = -1,                           \
 473        }
 474
 475#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
 476                                mw, mf, ds, dw, df, dt)         \
 477        {                                                       \
 478                .id             = _id,                          \
 479                .branch_type    = branch_composite,             \
 480                .name           = cname,                        \
 481                .parent_names   = pnames,                       \
 482                .num_parents    = ARRAY_SIZE(pnames),           \
 483                .flags          = f,                            \
 484                .muxdiv_offset  = mo,                           \
 485                .mux_shift      = ms,                           \
 486                .mux_width      = mw,                           \
 487                .mux_flags      = mf,                           \
 488                .div_shift      = ds,                           \
 489                .div_width      = dw,                           \
 490                .div_flags      = df,                           \
 491                .div_table      = dt,                           \
 492                .gate_offset    = -1,                           \
 493        }
 494
 495#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
 496        {                                                       \
 497                .id             = _id,                          \
 498                .branch_type    = branch_fraction_divider,      \
 499                .name           = cname,                        \
 500                .parent_names   = (const char *[]){ pname },    \
 501                .num_parents    = 1,                            \
 502                .flags          = f,                            \
 503                .muxdiv_offset  = mo,                           \
 504                .div_shift      = 16,                           \
 505                .div_width      = 16,                           \
 506                .div_flags      = df,                           \
 507                .gate_offset    = go,                           \
 508                .gate_shift     = gs,                           \
 509                .gate_flags     = gf,                           \
 510        }
 511
 512#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
 513        {                                                       \
 514                .id             = _id,                          \
 515                .branch_type    = branch_fraction_divider,      \
 516                .name           = cname,                        \
 517                .parent_names   = (const char *[]){ pname },    \
 518                .num_parents    = 1,                            \
 519                .flags          = f,                            \
 520                .muxdiv_offset  = mo,                           \
 521                .div_shift      = 16,                           \
 522                .div_width      = 16,                           \
 523                .div_flags      = df,                           \
 524                .gate_offset    = go,                           \
 525                .gate_shift     = gs,                           \
 526                .gate_flags     = gf,                           \
 527                .child          = ch,                           \
 528        }
 529
 530#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
 531        {                                                       \
 532                .id             = _id,                          \
 533                .branch_type    = branch_fraction_divider,      \
 534                .name           = cname,                        \
 535                .parent_names   = (const char *[]){ pname },    \
 536                .num_parents    = 1,                            \
 537                .flags          = f,                            \
 538                .muxdiv_offset  = mo,                           \
 539                .div_shift      = 16,                           \
 540                .div_width      = 16,                           \
 541                .div_flags      = df,                           \
 542                .gate_offset    = -1,                           \
 543                .child          = ch,                           \
 544        }
 545
 546#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,     \
 547                         ds, dw, df)                            \
 548        {                                                       \
 549                .id             = _id,                          \
 550                .branch_type    = branch_ddrclk,                \
 551                .name           = cname,                        \
 552                .parent_names   = pnames,                       \
 553                .num_parents    = ARRAY_SIZE(pnames),           \
 554                .flags          = f,                            \
 555                .muxdiv_offset  = mo,                           \
 556                .mux_shift      = ms,                           \
 557                .mux_width      = mw,                           \
 558                .div_shift      = ds,                           \
 559                .div_width      = dw,                           \
 560                .div_flags      = df,                           \
 561                .gate_offset    = -1,                           \
 562        }
 563
 564#define MUX(_id, cname, pnames, f, o, s, w, mf)                 \
 565        {                                                       \
 566                .id             = _id,                          \
 567                .branch_type    = branch_mux,                   \
 568                .name           = cname,                        \
 569                .parent_names   = pnames,                       \
 570                .num_parents    = ARRAY_SIZE(pnames),           \
 571                .flags          = f,                            \
 572                .muxdiv_offset  = o,                            \
 573                .mux_shift      = s,                            \
 574                .mux_width      = w,                            \
 575                .mux_flags      = mf,                           \
 576                .gate_offset    = -1,                           \
 577        }
 578
 579#define MUXGRF(_id, cname, pnames, f, o, s, w, mf)              \
 580        {                                                       \
 581                .id             = _id,                          \
 582                .branch_type    = branch_muxgrf,                \
 583                .name           = cname,                        \
 584                .parent_names   = pnames,                       \
 585                .num_parents    = ARRAY_SIZE(pnames),           \
 586                .flags          = f,                            \
 587                .muxdiv_offset  = o,                            \
 588                .mux_shift      = s,                            \
 589                .mux_width      = w,                            \
 590                .mux_flags      = mf,                           \
 591                .gate_offset    = -1,                           \
 592        }
 593
 594#define DIV(_id, cname, pname, f, o, s, w, df)                  \
 595        {                                                       \
 596                .id             = _id,                          \
 597                .branch_type    = branch_divider,               \
 598                .name           = cname,                        \
 599                .parent_names   = (const char *[]){ pname },    \
 600                .num_parents    = 1,                            \
 601                .flags          = f,                            \
 602                .muxdiv_offset  = o,                            \
 603                .div_shift      = s,                            \
 604                .div_width      = w,                            \
 605                .div_flags      = df,                           \
 606                .gate_offset    = -1,                           \
 607        }
 608
 609#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)           \
 610        {                                                       \
 611                .id             = _id,                          \
 612                .branch_type    = branch_divider,               \
 613                .name           = cname,                        \
 614                .parent_names   = (const char *[]){ pname },    \
 615                .num_parents    = 1,                            \
 616                .flags          = f,                            \
 617                .muxdiv_offset  = o,                            \
 618                .div_shift      = s,                            \
 619                .div_width      = w,                            \
 620                .div_flags      = df,                           \
 621                .div_table      = dt,                           \
 622        }
 623
 624#define GATE(_id, cname, pname, f, o, b, gf)                    \
 625        {                                                       \
 626                .id             = _id,                          \
 627                .branch_type    = branch_gate,                  \
 628                .name           = cname,                        \
 629                .parent_names   = (const char *[]){ pname },    \
 630                .num_parents    = 1,                            \
 631                .flags          = f,                            \
 632                .gate_offset    = o,                            \
 633                .gate_shift     = b,                            \
 634                .gate_flags     = gf,                           \
 635        }
 636
 637#define MMC(_id, cname, pname, offset, shift)                   \
 638        {                                                       \
 639                .id             = _id,                          \
 640                .branch_type    = branch_mmc,                   \
 641                .name           = cname,                        \
 642                .parent_names   = (const char *[]){ pname },    \
 643                .num_parents    = 1,                            \
 644                .muxdiv_offset  = offset,                       \
 645                .div_shift      = shift,                        \
 646        }
 647
 648#define INVERTER(_id, cname, pname, io, is, if)                 \
 649        {                                                       \
 650                .id             = _id,                          \
 651                .branch_type    = branch_inverter,              \
 652                .name           = cname,                        \
 653                .parent_names   = (const char *[]){ pname },    \
 654                .num_parents    = 1,                            \
 655                .muxdiv_offset  = io,                           \
 656                .div_shift      = is,                           \
 657                .div_flags      = if,                           \
 658        }
 659
 660#define FACTOR(_id, cname, pname,  f, fm, fd)                   \
 661        {                                                       \
 662                .id             = _id,                          \
 663                .branch_type    = branch_factor,                \
 664                .name           = cname,                        \
 665                .parent_names   = (const char *[]){ pname },    \
 666                .num_parents    = 1,                            \
 667                .flags          = f,                            \
 668                .div_shift      = fm,                           \
 669                .div_width      = fd,                           \
 670        }
 671
 672#define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
 673        {                                                       \
 674                .id             = _id,                          \
 675                .branch_type    = branch_factor,                \
 676                .name           = cname,                        \
 677                .parent_names   = (const char *[]){ pname },    \
 678                .num_parents    = 1,                            \
 679                .flags          = f,                            \
 680                .div_shift      = fm,                           \
 681                .div_width      = fd,                           \
 682                .gate_offset    = go,                           \
 683                .gate_shift     = gb,                           \
 684                .gate_flags     = gf,                           \
 685        }
 686
 687struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
 688                        void __iomem *base, unsigned long nr_clks);
 689void rockchip_clk_of_add_provider(struct device_node *np,
 690                                struct rockchip_clk_provider *ctx);
 691void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
 692                             struct clk *clk, unsigned int id);
 693void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
 694                                    struct rockchip_clk_branch *list,
 695                                    unsigned int nr_clk);
 696void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
 697                                struct rockchip_pll_clock *pll_list,
 698                                unsigned int nr_pll, int grf_lock_offset);
 699void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 700                        unsigned int lookup_id, const char *name,
 701                        const char *const *parent_names, u8 num_parents,
 702                        const struct rockchip_cpuclk_reg_data *reg_data,
 703                        const struct rockchip_cpuclk_rate_table *rates,
 704                        int nrates);
 705void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
 706void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
 707                                        unsigned int reg, void (*cb)(void));
 708
 709#define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
 710
 711#ifdef CONFIG_RESET_CONTROLLER
 712void rockchip_register_softrst(struct device_node *np,
 713                               unsigned int num_regs,
 714                               void __iomem *base, u8 flags);
 715#else
 716static inline void rockchip_register_softrst(struct device_node *np,
 717                               unsigned int num_regs,
 718                               void __iomem *base, u8 flags)
 719{
 720}
 721#endif
 722
 723#endif
 724