Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (c) 2014 MundoReader S.L.
0004  * Author: Heiko Stuebner <heiko@sntech.de>
0005  *
0006  * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
0007  * Author: Xing Zheng <zhengxing@rock-chips.com>
0008  *
0009  * based on
0010  *
0011  * samsung/clk.h
0012  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
0013  * Copyright (c) 2013 Linaro Ltd.
0014  * Author: Thomas Abraham <thomas.ab@samsung.com>
0015  */
0016 
0017 #ifndef CLK_ROCKCHIP_CLK_H
0018 #define CLK_ROCKCHIP_CLK_H
0019 
0020 #include <linux/io.h>
0021 #include <linux/clk-provider.h>
0022 
0023 struct clk;
0024 
0025 #define HIWORD_UPDATE(val, mask, shift) \
0026         ((val) << (shift) | (mask) << ((shift) + 16))
0027 
0028 /* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
0029 #define BOOST_PLL_H_CON(x)      ((x) * 0x4)
0030 #define BOOST_CLK_CON           0x0008
0031 #define BOOST_BOOST_CON         0x000c
0032 #define BOOST_SWITCH_CNT        0x0010
0033 #define BOOST_HIGH_PERF_CNT0        0x0014
0034 #define BOOST_HIGH_PERF_CNT1        0x0018
0035 #define BOOST_STATIS_THRESHOLD      0x001c
0036 #define BOOST_SHORT_SWITCH_CNT      0x0020
0037 #define BOOST_SWITCH_THRESHOLD      0x0024
0038 #define BOOST_FSM_STATUS        0x0028
0039 #define BOOST_PLL_L_CON(x)      ((x) * 0x4 + 0x2c)
0040 #define BOOST_RECOVERY_MASK     0x1
0041 #define BOOST_RECOVERY_SHIFT        1
0042 #define BOOST_SW_CTRL_MASK      0x1
0043 #define BOOST_SW_CTRL_SHIFT     2
0044 #define BOOST_LOW_FREQ_EN_MASK      0x1
0045 #define BOOST_LOW_FREQ_EN_SHIFT     3
0046 #define BOOST_BUSY_STATE        BIT(8)
0047 
0048 #define PX30_PLL_CON(x)         ((x) * 0x4)
0049 #define PX30_CLKSEL_CON(x)      ((x) * 0x4 + 0x100)
0050 #define PX30_CLKGATE_CON(x)     ((x) * 0x4 + 0x200)
0051 #define PX30_GLB_SRST_FST       0xb8
0052 #define PX30_GLB_SRST_SND       0xbc
0053 #define PX30_SOFTRST_CON(x)     ((x) * 0x4 + 0x300)
0054 #define PX30_MODE_CON           0xa0
0055 #define PX30_MISC_CON           0xa4
0056 #define PX30_SDMMC_CON0         0x380
0057 #define PX30_SDMMC_CON1         0x384
0058 #define PX30_SDIO_CON0          0x388
0059 #define PX30_SDIO_CON1          0x38c
0060 #define PX30_EMMC_CON0          0x390
0061 #define PX30_EMMC_CON1          0x394
0062 
0063 #define PX30_PMU_PLL_CON(x)     ((x) * 0x4)
0064 #define PX30_PMU_CLKSEL_CON(x)      ((x) * 0x4 + 0x40)
0065 #define PX30_PMU_CLKGATE_CON(x)     ((x) * 0x4 + 0x80)
0066 #define PX30_PMU_MODE           0x0020
0067 
0068 #define RV1108_PLL_CON(x)       ((x) * 0x4)
0069 #define RV1108_CLKSEL_CON(x)        ((x) * 0x4 + 0x60)
0070 #define RV1108_CLKGATE_CON(x)       ((x) * 0x4 + 0x120)
0071 #define RV1108_SOFTRST_CON(x)       ((x) * 0x4 + 0x180)
0072 #define RV1108_GLB_SRST_FST     0x1c0
0073 #define RV1108_GLB_SRST_SND     0x1c4
0074 #define RV1108_MISC_CON         0x1cc
0075 #define RV1108_SDMMC_CON0       0x1d8
0076 #define RV1108_SDMMC_CON1       0x1dc
0077 #define RV1108_SDIO_CON0        0x1e0
0078 #define RV1108_SDIO_CON1        0x1e4
0079 #define RV1108_EMMC_CON0        0x1e8
0080 #define RV1108_EMMC_CON1        0x1ec
0081 
0082 #define RK2928_PLL_CON(x)       ((x) * 0x4)
0083 #define RK2928_MODE_CON     0x40
0084 #define RK2928_CLKSEL_CON(x)    ((x) * 0x4 + 0x44)
0085 #define RK2928_CLKGATE_CON(x)   ((x) * 0x4 + 0xd0)
0086 #define RK2928_GLB_SRST_FST     0x100
0087 #define RK2928_GLB_SRST_SND     0x104
0088 #define RK2928_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
0089 #define RK2928_MISC_CON     0x134
0090 
0091 #define RK3036_SDMMC_CON0       0x144
0092 #define RK3036_SDMMC_CON1       0x148
0093 #define RK3036_SDIO_CON0        0x14c
0094 #define RK3036_SDIO_CON1        0x150
0095 #define RK3036_EMMC_CON0        0x154
0096 #define RK3036_EMMC_CON1        0x158
0097 
0098 #define RK3228_GLB_SRST_FST     0x1f0
0099 #define RK3228_GLB_SRST_SND     0x1f4
0100 #define RK3228_SDMMC_CON0       0x1c0
0101 #define RK3228_SDMMC_CON1       0x1c4
0102 #define RK3228_SDIO_CON0        0x1c8
0103 #define RK3228_SDIO_CON1        0x1cc
0104 #define RK3228_EMMC_CON0        0x1d8
0105 #define RK3228_EMMC_CON1        0x1dc
0106 
0107 #define RK3288_PLL_CON(x)       RK2928_PLL_CON(x)
0108 #define RK3288_MODE_CON         0x50
0109 #define RK3288_CLKSEL_CON(x)        ((x) * 0x4 + 0x60)
0110 #define RK3288_CLKGATE_CON(x)       ((x) * 0x4 + 0x160)
0111 #define RK3288_GLB_SRST_FST     0x1b0
0112 #define RK3288_GLB_SRST_SND     0x1b4
0113 #define RK3288_SOFTRST_CON(x)       ((x) * 0x4 + 0x1b8)
0114 #define RK3288_MISC_CON         0x1e8
0115 #define RK3288_SDMMC_CON0       0x200
0116 #define RK3288_SDMMC_CON1       0x204
0117 #define RK3288_SDIO0_CON0       0x208
0118 #define RK3288_SDIO0_CON1       0x20c
0119 #define RK3288_SDIO1_CON0       0x210
0120 #define RK3288_SDIO1_CON1       0x214
0121 #define RK3288_EMMC_CON0        0x218
0122 #define RK3288_EMMC_CON1        0x21c
0123 
0124 #define RK3308_PLL_CON(x)       RK2928_PLL_CON(x)
0125 #define RK3308_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
0126 #define RK3308_CLKGATE_CON(x)       ((x) * 0x4 + 0x300)
0127 #define RK3308_GLB_SRST_FST     0xb8
0128 #define RK3308_SOFTRST_CON(x)       ((x) * 0x4 + 0x400)
0129 #define RK3308_MODE_CON         0xa0
0130 #define RK3308_SDMMC_CON0       0x480
0131 #define RK3308_SDMMC_CON1       0x484
0132 #define RK3308_SDIO_CON0        0x488
0133 #define RK3308_SDIO_CON1        0x48c
0134 #define RK3308_EMMC_CON0        0x490
0135 #define RK3308_EMMC_CON1        0x494
0136 
0137 #define RK3328_PLL_CON(x)       RK2928_PLL_CON(x)
0138 #define RK3328_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
0139 #define RK3328_CLKGATE_CON(x)       ((x) * 0x4 + 0x200)
0140 #define RK3328_GRFCLKSEL_CON(x)     ((x) * 0x4 + 0x100)
0141 #define RK3328_GLB_SRST_FST     0x9c
0142 #define RK3328_GLB_SRST_SND     0x98
0143 #define RK3328_SOFTRST_CON(x)       ((x) * 0x4 + 0x300)
0144 #define RK3328_MODE_CON         0x80
0145 #define RK3328_MISC_CON         0x84
0146 #define RK3328_SDMMC_CON0       0x380
0147 #define RK3328_SDMMC_CON1       0x384
0148 #define RK3328_SDIO_CON0        0x388
0149 #define RK3328_SDIO_CON1        0x38c
0150 #define RK3328_EMMC_CON0        0x390
0151 #define RK3328_EMMC_CON1        0x394
0152 #define RK3328_SDMMC_EXT_CON0       0x398
0153 #define RK3328_SDMMC_EXT_CON1       0x39C
0154 
0155 #define RK3368_PLL_CON(x)       RK2928_PLL_CON(x)
0156 #define RK3368_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
0157 #define RK3368_CLKGATE_CON(x)       ((x) * 0x4 + 0x200)
0158 #define RK3368_GLB_SRST_FST     0x280
0159 #define RK3368_GLB_SRST_SND     0x284
0160 #define RK3368_SOFTRST_CON(x)       ((x) * 0x4 + 0x300)
0161 #define RK3368_MISC_CON         0x380
0162 #define RK3368_SDMMC_CON0       0x400
0163 #define RK3368_SDMMC_CON1       0x404
0164 #define RK3368_SDIO0_CON0       0x408
0165 #define RK3368_SDIO0_CON1       0x40c
0166 #define RK3368_SDIO1_CON0       0x410
0167 #define RK3368_SDIO1_CON1       0x414
0168 #define RK3368_EMMC_CON0        0x418
0169 #define RK3368_EMMC_CON1        0x41c
0170 
0171 #define RK3399_PLL_CON(x)       RK2928_PLL_CON(x)
0172 #define RK3399_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
0173 #define RK3399_CLKGATE_CON(x)       ((x) * 0x4 + 0x300)
0174 #define RK3399_SOFTRST_CON(x)       ((x) * 0x4 + 0x400)
0175 #define RK3399_GLB_SRST_FST     0x500
0176 #define RK3399_GLB_SRST_SND     0x504
0177 #define RK3399_GLB_CNT_TH       0x508
0178 #define RK3399_MISC_CON         0x50c
0179 #define RK3399_RST_CON          0x510
0180 #define RK3399_RST_ST           0x514
0181 #define RK3399_SDMMC_CON0       0x580
0182 #define RK3399_SDMMC_CON1       0x584
0183 #define RK3399_SDIO_CON0        0x588
0184 #define RK3399_SDIO_CON1        0x58c
0185 
0186 #define RK3399_PMU_PLL_CON(x)       RK2928_PLL_CON(x)
0187 #define RK3399_PMU_CLKSEL_CON(x)    ((x) * 0x4 + 0x80)
0188 #define RK3399_PMU_CLKGATE_CON(x)   ((x) * 0x4 + 0x100)
0189 #define RK3399_PMU_SOFTRST_CON(x)   ((x) * 0x4 + 0x110)
0190 
0191 #define RK3568_PLL_CON(x)       RK2928_PLL_CON(x)
0192 #define RK3568_MODE_CON0        0xc0
0193 #define RK3568_MISC_CON0        0xc4
0194 #define RK3568_MISC_CON1        0xc8
0195 #define RK3568_MISC_CON2        0xcc
0196 #define RK3568_GLB_CNT_TH       0xd0
0197 #define RK3568_GLB_SRST_FST     0xd4
0198 #define RK3568_GLB_SRST_SND     0xd8
0199 #define RK3568_GLB_RST_CON      0xdc
0200 #define RK3568_GLB_RST_ST       0xe0
0201 #define RK3568_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
0202 #define RK3568_CLKGATE_CON(x)       ((x) * 0x4 + 0x300)
0203 #define RK3568_SOFTRST_CON(x)       ((x) * 0x4 + 0x400)
0204 #define RK3568_SDMMC0_CON0      0x580
0205 #define RK3568_SDMMC0_CON1      0x584
0206 #define RK3568_SDMMC1_CON0      0x588
0207 #define RK3568_SDMMC1_CON1      0x58c
0208 #define RK3568_SDMMC2_CON0      0x590
0209 #define RK3568_SDMMC2_CON1      0x594
0210 #define RK3568_EMMC_CON0        0x598
0211 #define RK3568_EMMC_CON1        0x59c
0212 
0213 #define RK3568_PMU_PLL_CON(x)       RK2928_PLL_CON(x)
0214 #define RK3568_PMU_MODE_CON0        0x80
0215 #define RK3568_PMU_CLKSEL_CON(x)    ((x) * 0x4 + 0x100)
0216 #define RK3568_PMU_CLKGATE_CON(x)   ((x) * 0x4 + 0x180)
0217 #define RK3568_PMU_SOFTRST_CON(x)   ((x) * 0x4 + 0x200)
0218 
0219 enum rockchip_pll_type {
0220     pll_rk3036,
0221     pll_rk3066,
0222     pll_rk3328,
0223     pll_rk3399,
0224 };
0225 
0226 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,  \
0227             _postdiv2, _dsmpd, _frac)       \
0228 {                               \
0229     .rate   = _rate##U,                 \
0230     .fbdiv = _fbdiv,                    \
0231     .postdiv1 = _postdiv1,                  \
0232     .refdiv = _refdiv,                  \
0233     .postdiv2 = _postdiv2,                  \
0234     .dsmpd = _dsmpd,                    \
0235     .frac = _frac,                      \
0236 }
0237 
0238 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)   \
0239 {                       \
0240     .rate   = _rate##U,         \
0241     .nr = _nr,              \
0242     .nf = _nf,              \
0243     .no = _no,              \
0244     .nb = ((_nf) < 2) ? 1 : (_nf) >> 1, \
0245 }
0246 
0247 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb)       \
0248 {                               \
0249     .rate   = _rate##U,                 \
0250     .nr = _nr,                      \
0251     .nf = _nf,                      \
0252     .no = _no,                      \
0253     .nb = _nb,                      \
0254 }
0255 
0256 /**
0257  * struct rockchip_clk_provider - information about clock provider
0258  * @reg_base: virtual address for the register base.
0259  * @clk_data: holds clock related data like clk* and number of clocks.
0260  * @cru_node: device-node of the clock-provider
0261  * @grf: regmap of the general-register-files syscon
0262  * @lock: maintains exclusion between callbacks for a given clock-provider.
0263  */
0264 struct rockchip_clk_provider {
0265     void __iomem *reg_base;
0266     struct clk_onecell_data clk_data;
0267     struct device_node *cru_node;
0268     struct regmap *grf;
0269     spinlock_t lock;
0270 };
0271 
0272 struct rockchip_pll_rate_table {
0273     unsigned long rate;
0274     union {
0275         struct {
0276             /* for RK3066 */
0277             unsigned int nr;
0278             unsigned int nf;
0279             unsigned int no;
0280             unsigned int nb;
0281         };
0282         struct {
0283             /* for RK3036/RK3399 */
0284             unsigned int fbdiv;
0285             unsigned int postdiv1;
0286             unsigned int refdiv;
0287             unsigned int postdiv2;
0288             unsigned int dsmpd;
0289             unsigned int frac;
0290         };
0291     };
0292 };
0293 
0294 /**
0295  * struct rockchip_pll_clock - information about pll clock
0296  * @id: platform specific id of the clock.
0297  * @name: name of this pll clock.
0298  * @parent_names: name of the parent clock.
0299  * @num_parents: number of parents
0300  * @flags: optional flags for basic clock.
0301  * @con_offset: offset of the register for configuring the PLL.
0302  * @mode_offset: offset of the register for configuring the PLL-mode.
0303  * @mode_shift: offset inside the mode-register for the mode of this pll.
0304  * @lock_shift: offset inside the lock register for the lock status.
0305  * @type: Type of PLL to be registered.
0306  * @pll_flags: hardware-specific flags
0307  * @rate_table: Table of usable pll rates
0308  *
0309  * Flags:
0310  * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the
0311  *  rate_table parameters and ajust them if necessary.
0312  */
0313 struct rockchip_pll_clock {
0314     unsigned int        id;
0315     const char      *name;
0316     const char      *const *parent_names;
0317     u8          num_parents;
0318     unsigned long       flags;
0319     int         con_offset;
0320     int         mode_offset;
0321     int         mode_shift;
0322     int         lock_shift;
0323     enum rockchip_pll_type  type;
0324     u8          pll_flags;
0325     struct rockchip_pll_rate_table *rate_table;
0326 };
0327 
0328 #define ROCKCHIP_PLL_SYNC_RATE      BIT(0)
0329 
0330 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift,   \
0331         _lshift, _pflags, _rtable)              \
0332     {                               \
0333         .id     = _id,                  \
0334         .type       = _type,                \
0335         .name       = _name,                \
0336         .parent_names   = _pnames,              \
0337         .num_parents    = ARRAY_SIZE(_pnames),          \
0338         .flags      = CLK_GET_RATE_NOCACHE | _flags,    \
0339         .con_offset = _con,                 \
0340         .mode_offset    = _mode,                \
0341         .mode_shift = _mshift,              \
0342         .lock_shift = _lshift,              \
0343         .pll_flags  = _pflags,              \
0344         .rate_table = _rtable,              \
0345     }
0346 
0347 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
0348         enum rockchip_pll_type pll_type,
0349         const char *name, const char *const *parent_names,
0350         u8 num_parents, int con_offset, int grf_lock_offset,
0351         int lock_shift, int mode_offset, int mode_shift,
0352         struct rockchip_pll_rate_table *rate_table,
0353         unsigned long flags, u8 clk_pll_flags);
0354 
0355 struct rockchip_cpuclk_clksel {
0356     int reg;
0357     u32 val;
0358 };
0359 
0360 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS    5
0361 #define ROCKCHIP_CPUCLK_MAX_CORES   4
0362 struct rockchip_cpuclk_rate_table {
0363     unsigned long prate;
0364     struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
0365 };
0366 
0367 /**
0368  * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock
0369  * @core_reg[]: register offset of the cores setting register
0370  * @div_core_shift[]:   cores divider offset used to divide the pll value
0371  * @div_core_mask[]:    cores divider mask
0372  * @num_cores:  number of cpu cores
0373  * @mux_core_main:  mux value to select main parent of core
0374  * @mux_core_shift: offset of the core multiplexer
0375  * @mux_core_mask:  core multiplexer mask
0376  */
0377 struct rockchip_cpuclk_reg_data {
0378     int core_reg[ROCKCHIP_CPUCLK_MAX_CORES];
0379     u8  div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES];
0380     u32 div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES];
0381     int num_cores;
0382     u8  mux_core_alt;
0383     u8  mux_core_main;
0384     u8  mux_core_shift;
0385     u32 mux_core_mask;
0386 };
0387 
0388 struct clk *rockchip_clk_register_cpuclk(const char *name,
0389             const char *const *parent_names, u8 num_parents,
0390             const struct rockchip_cpuclk_reg_data *reg_data,
0391             const struct rockchip_cpuclk_rate_table *rates,
0392             int nrates, void __iomem *reg_base, spinlock_t *lock);
0393 
0394 struct clk *rockchip_clk_register_mmc(const char *name,
0395                 const char *const *parent_names, u8 num_parents,
0396                 void __iomem *reg, int shift);
0397 
0398 /*
0399  * DDRCLK flags, including method of setting the rate
0400  * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
0401  */
0402 #define ROCKCHIP_DDRCLK_SIP     BIT(0)
0403 
0404 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
0405                      const char *const *parent_names,
0406                      u8 num_parents, int mux_offset,
0407                      int mux_shift, int mux_width,
0408                      int div_shift, int div_width,
0409                      int ddr_flags, void __iomem *reg_base,
0410                      spinlock_t *lock);
0411 
0412 #define ROCKCHIP_INVERTER_HIWORD_MASK   BIT(0)
0413 
0414 struct clk *rockchip_clk_register_inverter(const char *name,
0415                 const char *const *parent_names, u8 num_parents,
0416                 void __iomem *reg, int shift, int flags,
0417                 spinlock_t *lock);
0418 
0419 struct clk *rockchip_clk_register_muxgrf(const char *name,
0420                 const char *const *parent_names, u8 num_parents,
0421                 int flags, struct regmap *grf, int reg,
0422                 int shift, int width, int mux_flags);
0423 
0424 #define PNAME(x) static const char *const x[] __initconst
0425 
0426 enum rockchip_clk_branch_type {
0427     branch_composite,
0428     branch_mux,
0429     branch_muxgrf,
0430     branch_divider,
0431     branch_fraction_divider,
0432     branch_gate,
0433     branch_mmc,
0434     branch_inverter,
0435     branch_factor,
0436     branch_ddrclk,
0437     branch_half_divider,
0438 };
0439 
0440 struct rockchip_clk_branch {
0441     unsigned int            id;
0442     enum rockchip_clk_branch_type   branch_type;
0443     const char          *name;
0444     const char          *const *parent_names;
0445     u8              num_parents;
0446     unsigned long           flags;
0447     int             muxdiv_offset;
0448     u8              mux_shift;
0449     u8              mux_width;
0450     u8              mux_flags;
0451     int             div_offset;
0452     u8              div_shift;
0453     u8              div_width;
0454     u8              div_flags;
0455     struct clk_div_table        *div_table;
0456     int             gate_offset;
0457     u8              gate_shift;
0458     u8              gate_flags;
0459     struct rockchip_clk_branch  *child;
0460 };
0461 
0462 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
0463           df, go, gs, gf)               \
0464     {                           \
0465         .id     = _id,              \
0466         .branch_type    = branch_composite,     \
0467         .name       = cname,            \
0468         .parent_names   = pnames,           \
0469         .num_parents    = ARRAY_SIZE(pnames),       \
0470         .flags      = f,                \
0471         .muxdiv_offset  = mo,               \
0472         .mux_shift  = ms,               \
0473         .mux_width  = mw,               \
0474         .mux_flags  = mf,               \
0475         .div_shift  = ds,               \
0476         .div_width  = dw,               \
0477         .div_flags  = df,               \
0478         .gate_offset    = go,               \
0479         .gate_shift = gs,               \
0480         .gate_flags = gf,               \
0481     }
0482 
0483 #define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \
0484                  mf, do, ds, dw, df, go, gs, gf)    \
0485     {                           \
0486         .id     = _id,              \
0487         .branch_type    = branch_composite,     \
0488         .name       = cname,            \
0489         .parent_names   = pnames,           \
0490         .num_parents    = ARRAY_SIZE(pnames),       \
0491         .flags      = f,                \
0492         .muxdiv_offset  = mo,               \
0493         .mux_shift  = ms,               \
0494         .mux_width  = mw,               \
0495         .mux_flags  = mf,               \
0496         .div_offset = do,               \
0497         .div_shift  = ds,               \
0498         .div_width  = dw,               \
0499         .div_flags  = df,               \
0500         .gate_offset    = go,               \
0501         .gate_shift = gs,               \
0502         .gate_flags = gf,               \
0503     }
0504 
0505 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df,   \
0506             go, gs, gf)             \
0507     {                           \
0508         .id     = _id,              \
0509         .branch_type    = branch_composite,     \
0510         .name       = cname,            \
0511         .parent_names   = (const char *[]){ pname },    \
0512         .num_parents    = 1,                \
0513         .flags      = f,                \
0514         .muxdiv_offset  = mo,               \
0515         .div_shift  = ds,               \
0516         .div_width  = dw,               \
0517         .div_flags  = df,               \
0518         .gate_offset    = go,               \
0519         .gate_shift = gs,               \
0520         .gate_flags = gf,               \
0521     }
0522 
0523 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\
0524                    df, dt, go, gs, gf)      \
0525     {                           \
0526         .id     = _id,              \
0527         .branch_type    = branch_composite,     \
0528         .name       = cname,            \
0529         .parent_names   = (const char *[]){ pname },    \
0530         .num_parents    = 1,                \
0531         .flags      = f,                \
0532         .muxdiv_offset  = mo,               \
0533         .div_shift  = ds,               \
0534         .div_width  = dw,               \
0535         .div_flags  = df,               \
0536         .div_table  = dt,               \
0537         .gate_offset    = go,               \
0538         .gate_shift = gs,               \
0539         .gate_flags = gf,               \
0540     }
0541 
0542 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf,  \
0543             go, gs, gf)             \
0544     {                           \
0545         .id     = _id,              \
0546         .branch_type    = branch_composite,     \
0547         .name       = cname,            \
0548         .parent_names   = pnames,           \
0549         .num_parents    = ARRAY_SIZE(pnames),       \
0550         .flags      = f,                \
0551         .muxdiv_offset  = mo,               \
0552         .mux_shift  = ms,               \
0553         .mux_width  = mw,               \
0554         .mux_flags  = mf,               \
0555         .gate_offset    = go,               \
0556         .gate_shift = gs,               \
0557         .gate_flags = gf,               \
0558     }
0559 
0560 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \
0561              ds, dw, df)                \
0562     {                           \
0563         .id     = _id,              \
0564         .branch_type    = branch_composite,     \
0565         .name       = cname,            \
0566         .parent_names   = pnames,           \
0567         .num_parents    = ARRAY_SIZE(pnames),       \
0568         .flags      = f,                \
0569         .muxdiv_offset  = mo,               \
0570         .mux_shift  = ms,               \
0571         .mux_width  = mw,               \
0572         .mux_flags  = mf,               \
0573         .div_shift  = ds,               \
0574         .div_width  = dw,               \
0575         .div_flags  = df,               \
0576         .gate_offset    = -1,               \
0577     }
0578 
0579 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms,  \
0580                 mw, mf, ds, dw, df, dt)     \
0581     {                           \
0582         .id     = _id,              \
0583         .branch_type    = branch_composite,     \
0584         .name       = cname,            \
0585         .parent_names   = pnames,           \
0586         .num_parents    = ARRAY_SIZE(pnames),       \
0587         .flags      = f,                \
0588         .muxdiv_offset  = mo,               \
0589         .mux_shift  = ms,               \
0590         .mux_width  = mw,               \
0591         .mux_flags  = mf,               \
0592         .div_shift  = ds,               \
0593         .div_width  = dw,               \
0594         .div_flags  = df,               \
0595         .div_table  = dt,               \
0596         .gate_offset    = -1,               \
0597     }
0598 
0599 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
0600     {                           \
0601         .id     = _id,              \
0602         .branch_type    = branch_fraction_divider,  \
0603         .name       = cname,            \
0604         .parent_names   = (const char *[]){ pname },    \
0605         .num_parents    = 1,                \
0606         .flags      = f,                \
0607         .muxdiv_offset  = mo,               \
0608         .div_shift  = 16,               \
0609         .div_width  = 16,               \
0610         .div_flags  = df,               \
0611         .gate_offset    = go,               \
0612         .gate_shift = gs,               \
0613         .gate_flags = gf,               \
0614     }
0615 
0616 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
0617     {                           \
0618         .id     = _id,              \
0619         .branch_type    = branch_fraction_divider,  \
0620         .name       = cname,            \
0621         .parent_names   = (const char *[]){ pname },    \
0622         .num_parents    = 1,                \
0623         .flags      = f,                \
0624         .muxdiv_offset  = mo,               \
0625         .div_shift  = 16,               \
0626         .div_width  = 16,               \
0627         .div_flags  = df,               \
0628         .gate_offset    = go,               \
0629         .gate_shift = gs,               \
0630         .gate_flags = gf,               \
0631         .child      = ch,               \
0632     }
0633 
0634 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
0635     {                           \
0636         .id     = _id,              \
0637         .branch_type    = branch_fraction_divider,  \
0638         .name       = cname,            \
0639         .parent_names   = (const char *[]){ pname },    \
0640         .num_parents    = 1,                \
0641         .flags      = f,                \
0642         .muxdiv_offset  = mo,               \
0643         .div_shift  = 16,               \
0644         .div_width  = 16,               \
0645         .div_flags  = df,               \
0646         .gate_offset    = -1,               \
0647         .child      = ch,               \
0648     }
0649 
0650 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \
0651              ds, dw, df)                \
0652     {                           \
0653         .id     = _id,              \
0654         .branch_type    = branch_ddrclk,        \
0655         .name       = cname,            \
0656         .parent_names   = pnames,           \
0657         .num_parents    = ARRAY_SIZE(pnames),       \
0658         .flags      = f,                \
0659         .muxdiv_offset  = mo,                           \
0660         .mux_shift      = ms,                           \
0661         .mux_width      = mw,                           \
0662         .div_shift      = ds,                           \
0663         .div_width      = dw,                           \
0664         .div_flags  = df,               \
0665         .gate_offset    = -1,                           \
0666     }
0667 
0668 #define MUX(_id, cname, pnames, f, o, s, w, mf)         \
0669     {                           \
0670         .id     = _id,              \
0671         .branch_type    = branch_mux,           \
0672         .name       = cname,            \
0673         .parent_names   = pnames,           \
0674         .num_parents    = ARRAY_SIZE(pnames),       \
0675         .flags      = f,                \
0676         .muxdiv_offset  = o,                \
0677         .mux_shift  = s,                \
0678         .mux_width  = w,                \
0679         .mux_flags  = mf,               \
0680         .gate_offset    = -1,               \
0681     }
0682 
0683 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf)      \
0684     {                           \
0685         .id     = _id,              \
0686         .branch_type    = branch_muxgrf,        \
0687         .name       = cname,            \
0688         .parent_names   = pnames,           \
0689         .num_parents    = ARRAY_SIZE(pnames),       \
0690         .flags      = f,                \
0691         .muxdiv_offset  = o,                \
0692         .mux_shift  = s,                \
0693         .mux_width  = w,                \
0694         .mux_flags  = mf,               \
0695         .gate_offset    = -1,               \
0696     }
0697 
0698 #define DIV(_id, cname, pname, f, o, s, w, df)          \
0699     {                           \
0700         .id     = _id,              \
0701         .branch_type    = branch_divider,       \
0702         .name       = cname,            \
0703         .parent_names   = (const char *[]){ pname },    \
0704         .num_parents    = 1,                \
0705         .flags      = f,                \
0706         .muxdiv_offset  = o,                \
0707         .div_shift  = s,                \
0708         .div_width  = w,                \
0709         .div_flags  = df,               \
0710         .gate_offset    = -1,               \
0711     }
0712 
0713 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt)       \
0714     {                           \
0715         .id     = _id,              \
0716         .branch_type    = branch_divider,       \
0717         .name       = cname,            \
0718         .parent_names   = (const char *[]){ pname },    \
0719         .num_parents    = 1,                \
0720         .flags      = f,                \
0721         .muxdiv_offset  = o,                \
0722         .div_shift  = s,                \
0723         .div_width  = w,                \
0724         .div_flags  = df,               \
0725         .div_table  = dt,               \
0726     }
0727 
0728 #define GATE(_id, cname, pname, f, o, b, gf)            \
0729     {                           \
0730         .id     = _id,              \
0731         .branch_type    = branch_gate,          \
0732         .name       = cname,            \
0733         .parent_names   = (const char *[]){ pname },    \
0734         .num_parents    = 1,                \
0735         .flags      = f,                \
0736         .gate_offset    = o,                \
0737         .gate_shift = b,                \
0738         .gate_flags = gf,               \
0739     }
0740 
0741 #define MMC(_id, cname, pname, offset, shift)           \
0742     {                           \
0743         .id     = _id,              \
0744         .branch_type    = branch_mmc,           \
0745         .name       = cname,            \
0746         .parent_names   = (const char *[]){ pname },    \
0747         .num_parents    = 1,                \
0748         .muxdiv_offset  = offset,           \
0749         .div_shift  = shift,            \
0750     }
0751 
0752 #define INVERTER(_id, cname, pname, io, is, if)         \
0753     {                           \
0754         .id     = _id,              \
0755         .branch_type    = branch_inverter,      \
0756         .name       = cname,            \
0757         .parent_names   = (const char *[]){ pname },    \
0758         .num_parents    = 1,                \
0759         .muxdiv_offset  = io,               \
0760         .div_shift  = is,               \
0761         .div_flags  = if,               \
0762     }
0763 
0764 #define FACTOR(_id, cname, pname,  f, fm, fd)           \
0765     {                           \
0766         .id     = _id,              \
0767         .branch_type    = branch_factor,        \
0768         .name       = cname,            \
0769         .parent_names   = (const char *[]){ pname },    \
0770         .num_parents    = 1,                \
0771         .flags      = f,                \
0772         .div_shift  = fm,               \
0773         .div_width  = fd,               \
0774     }
0775 
0776 #define FACTOR_GATE(_id, cname, pname,  f, fm, fd, go, gb, gf)  \
0777     {                           \
0778         .id     = _id,              \
0779         .branch_type    = branch_factor,        \
0780         .name       = cname,            \
0781         .parent_names   = (const char *[]){ pname },    \
0782         .num_parents    = 1,                \
0783         .flags      = f,                \
0784         .div_shift  = fm,               \
0785         .div_width  = fd,               \
0786         .gate_offset    = go,               \
0787         .gate_shift = gb,               \
0788         .gate_flags = gf,               \
0789     }
0790 
0791 #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
0792               df, go, gs, gf)               \
0793     {                           \
0794         .id     = _id,              \
0795         .branch_type    = branch_half_divider,      \
0796         .name       = cname,            \
0797         .parent_names   = pnames,           \
0798         .num_parents    = ARRAY_SIZE(pnames),       \
0799         .flags      = f,                \
0800         .muxdiv_offset  = mo,               \
0801         .mux_shift  = ms,               \
0802         .mux_width  = mw,               \
0803         .mux_flags  = mf,               \
0804         .div_shift  = ds,               \
0805         .div_width  = dw,               \
0806         .div_flags  = df,               \
0807         .gate_offset    = go,               \
0808         .gate_shift = gs,               \
0809         .gate_flags = gf,               \
0810     }
0811 
0812 #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \
0813                  ds, dw, df)                \
0814     {                           \
0815         .id     = _id,              \
0816         .branch_type    = branch_half_divider,      \
0817         .name       = cname,            \
0818         .parent_names   = pnames,           \
0819         .num_parents    = ARRAY_SIZE(pnames),       \
0820         .flags      = f,                \
0821         .muxdiv_offset  = mo,               \
0822         .mux_shift  = ms,               \
0823         .mux_width  = mw,               \
0824         .mux_flags  = mf,               \
0825         .div_shift  = ds,               \
0826         .div_width  = dw,               \
0827         .div_flags  = df,               \
0828         .gate_offset    = -1,               \
0829     }
0830 
0831 #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df,   \
0832             go, gs, gf)             \
0833     {                           \
0834         .id     = _id,              \
0835         .branch_type    = branch_half_divider,      \
0836         .name       = cname,            \
0837         .parent_names   = (const char *[]){ pname },    \
0838         .num_parents    = 1,                \
0839         .flags      = f,                \
0840         .muxdiv_offset  = mo,               \
0841         .div_shift  = ds,               \
0842         .div_width  = dw,               \
0843         .div_flags  = df,               \
0844         .gate_offset    = go,               \
0845         .gate_shift = gs,               \
0846         .gate_flags = gf,               \
0847     }
0848 
0849 #define DIV_HALF(_id, cname, pname, f, o, s, w, df)         \
0850     {                           \
0851         .id     = _id,              \
0852         .branch_type    = branch_half_divider,      \
0853         .name       = cname,            \
0854         .parent_names   = (const char *[]){ pname },    \
0855         .num_parents    = 1,                \
0856         .flags      = f,                \
0857         .muxdiv_offset  = o,                \
0858         .div_shift  = s,                \
0859         .div_width  = w,                \
0860         .div_flags  = df,               \
0861         .gate_offset    = -1,               \
0862     }
0863 
0864 /* SGRF clocks are only accessible from secure mode, so not controllable */
0865 #define SGRF_GATE(_id, cname, pname)                \
0866         FACTOR(_id, cname, pname, 0, 1, 1)
0867 
0868 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np,
0869             void __iomem *base, unsigned long nr_clks);
0870 void rockchip_clk_of_add_provider(struct device_node *np,
0871                 struct rockchip_clk_provider *ctx);
0872 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx,
0873                  struct clk *clk, unsigned int id);
0874 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
0875                     struct rockchip_clk_branch *list,
0876                     unsigned int nr_clk);
0877 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
0878                 struct rockchip_pll_clock *pll_list,
0879                 unsigned int nr_pll, int grf_lock_offset);
0880 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
0881             unsigned int lookup_id, const char *name,
0882             const char *const *parent_names, u8 num_parents,
0883             const struct rockchip_cpuclk_reg_data *reg_data,
0884             const struct rockchip_cpuclk_rate_table *rates,
0885             int nrates);
0886 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
0887 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
0888                     unsigned int reg, void (*cb)(void));
0889 
0890 #define ROCKCHIP_SOFTRST_HIWORD_MASK    BIT(0)
0891 
0892 struct clk *rockchip_clk_register_halfdiv(const char *name,
0893                       const char *const *parent_names,
0894                       u8 num_parents, void __iomem *base,
0895                       int muxdiv_offset, u8 mux_shift,
0896                       u8 mux_width, u8 mux_flags,
0897                       u8 div_shift, u8 div_width,
0898                       u8 div_flags, int gate_offset,
0899                       u8 gate_shift, u8 gate_flags,
0900                       unsigned long flags,
0901                       spinlock_t *lock);
0902 
0903 #ifdef CONFIG_RESET_CONTROLLER
0904 void rockchip_register_softrst(struct device_node *np,
0905                    unsigned int num_regs,
0906                    void __iomem *base, u8 flags);
0907 #else
0908 static inline void rockchip_register_softrst(struct device_node *np,
0909                    unsigned int num_regs,
0910                    void __iomem *base, u8 flags)
0911 {
0912 }
0913 #endif
0914 
0915 #endif