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