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