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