xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 44ae54af5cadb499cb72cc0edd71711d7a2d019e)
17c36209bSGhennadi Procopciuc /* SPDX-License-Identifier: BSD-3-Clause */
27c36209bSGhennadi Procopciuc /*
37c36209bSGhennadi Procopciuc  * Copyright 2020-2024 NXP
47c36209bSGhennadi Procopciuc  */
57c36209bSGhennadi Procopciuc #ifndef S32CC_CLK_MODULES_H
67c36209bSGhennadi Procopciuc #define S32CC_CLK_MODULES_H
77c36209bSGhennadi Procopciuc 
87c36209bSGhennadi Procopciuc #include <inttypes.h>
912e7a2cdSGhennadi Procopciuc #include <stdbool.h>
107c36209bSGhennadi Procopciuc #include <stddef.h>
117c36209bSGhennadi Procopciuc 
127c36209bSGhennadi Procopciuc #define MHZ	UL(1000000)
137c36209bSGhennadi Procopciuc #define GHZ	(UL(1000) * MHZ)
147c36209bSGhennadi Procopciuc 
157c36209bSGhennadi Procopciuc enum s32cc_clkm_type {
167c36209bSGhennadi Procopciuc 	s32cc_osc_t,
177c36209bSGhennadi Procopciuc 	s32cc_clk_t,
18a8be748aSGhennadi Procopciuc 	s32cc_pll_t,
19a8be748aSGhennadi Procopciuc 	s32cc_pll_out_div_t,
20*44ae54afSGhennadi Procopciuc 	s32cc_dfs_t,
21*44ae54afSGhennadi Procopciuc 	s32cc_dfs_div_t,
22a8be748aSGhennadi Procopciuc 	s32cc_clkmux_t,
233fa91a94SGhennadi Procopciuc 	s32cc_shared_clkmux_t,
2444e2130aSGhennadi Procopciuc 	s32cc_fixed_div_t,
257c36209bSGhennadi Procopciuc };
267c36209bSGhennadi Procopciuc 
277c36209bSGhennadi Procopciuc enum s32cc_clk_source {
287c36209bSGhennadi Procopciuc 	S32CC_FIRC,
297c36209bSGhennadi Procopciuc 	S32CC_FXOSC,
307c36209bSGhennadi Procopciuc 	S32CC_SIRC,
31a8be748aSGhennadi Procopciuc 	S32CC_ARM_PLL,
32*44ae54afSGhennadi Procopciuc 	S32CC_ARM_DFS,
333fa91a94SGhennadi Procopciuc 	S32CC_CGM1,
347c36209bSGhennadi Procopciuc };
357c36209bSGhennadi Procopciuc 
367c36209bSGhennadi Procopciuc struct s32cc_clk_obj {
377c36209bSGhennadi Procopciuc 	enum s32cc_clkm_type type;
387c36209bSGhennadi Procopciuc 	uint32_t refcount;
397c36209bSGhennadi Procopciuc };
407c36209bSGhennadi Procopciuc 
417c36209bSGhennadi Procopciuc struct s32cc_osc {
427c36209bSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
437c36209bSGhennadi Procopciuc 	enum s32cc_clk_source source;
447c36209bSGhennadi Procopciuc 	unsigned long freq;
457c36209bSGhennadi Procopciuc 	void *base;
467c36209bSGhennadi Procopciuc };
477c36209bSGhennadi Procopciuc 
487c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE)       \
497c36209bSGhennadi Procopciuc {                                    \
507c36209bSGhennadi Procopciuc 	.desc = {                    \
517c36209bSGhennadi Procopciuc 		.type = s32cc_osc_t, \
527c36209bSGhennadi Procopciuc 	},                           \
537c36209bSGhennadi Procopciuc 	.source = (SOURCE),          \
547c36209bSGhennadi Procopciuc }
557c36209bSGhennadi Procopciuc 
56a8be748aSGhennadi Procopciuc struct s32cc_clkmux {
57a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
58a8be748aSGhennadi Procopciuc 	enum s32cc_clk_source module;
59a8be748aSGhennadi Procopciuc 	uint8_t index; /* Mux index in parent module */
60a8be748aSGhennadi Procopciuc 	unsigned long source_id; /* Selected source */
61a8be748aSGhennadi Procopciuc 	uint8_t nclks; /* Number of input clocks */
62a8be748aSGhennadi Procopciuc 	unsigned long clkids[5]; /* IDs of the input clocks */
63a8be748aSGhennadi Procopciuc };
64a8be748aSGhennadi Procopciuc 
65a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
66a8be748aSGhennadi Procopciuc {                                                               \
67a8be748aSGhennadi Procopciuc 	.desc = {                                               \
68a8be748aSGhennadi Procopciuc 		.type = (TYPE),                                 \
69a8be748aSGhennadi Procopciuc 	},                                                      \
70a8be748aSGhennadi Procopciuc 	.module = (MODULE),                                     \
71a8be748aSGhennadi Procopciuc 	.index = (INDEX),                                       \
72a8be748aSGhennadi Procopciuc 	.nclks = (NCLKS),                                       \
73a8be748aSGhennadi Procopciuc 	.clkids = {__VA_ARGS__},                                \
74a8be748aSGhennadi Procopciuc }
75a8be748aSGhennadi Procopciuc 
76a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
77a8be748aSGhennadi Procopciuc 	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
78a8be748aSGhennadi Procopciuc 			       INDEX, NCLKS, __VA_ARGS__)
79a8be748aSGhennadi Procopciuc 
803fa91a94SGhennadi Procopciuc #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
813fa91a94SGhennadi Procopciuc 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
823fa91a94SGhennadi Procopciuc 			       INDEX, NCLKS, __VA_ARGS__)
833fa91a94SGhennadi Procopciuc 
84a8be748aSGhennadi Procopciuc struct s32cc_pll {
85a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
86a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj *source;
87a8be748aSGhennadi Procopciuc 	enum s32cc_clk_source instance;
88a8be748aSGhennadi Procopciuc 	unsigned long vco_freq;
89a8be748aSGhennadi Procopciuc 	uint32_t ndividers;
90a8be748aSGhennadi Procopciuc 	uintptr_t base;
91a8be748aSGhennadi Procopciuc };
92a8be748aSGhennadi Procopciuc 
93a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
94a8be748aSGhennadi Procopciuc {                                                        \
95a8be748aSGhennadi Procopciuc 	.desc = {                                        \
96a8be748aSGhennadi Procopciuc 		.type = s32cc_pll_t,                     \
97a8be748aSGhennadi Procopciuc 	},                                               \
98a8be748aSGhennadi Procopciuc 	.source = &(PLL_MUX_CLK).desc,                   \
99a8be748aSGhennadi Procopciuc 	.instance = (INSTANCE),                          \
100a8be748aSGhennadi Procopciuc 	.ndividers = (NDIVIDERS),                        \
101a8be748aSGhennadi Procopciuc }
102a8be748aSGhennadi Procopciuc 
103a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div {
104a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
105a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj *parent;
106a8be748aSGhennadi Procopciuc 	uint32_t index;
107a8be748aSGhennadi Procopciuc 	unsigned long freq;
108a8be748aSGhennadi Procopciuc };
109a8be748aSGhennadi Procopciuc 
110a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
111a8be748aSGhennadi Procopciuc {                                              \
112a8be748aSGhennadi Procopciuc 	.desc = {                              \
113a8be748aSGhennadi Procopciuc 		.type = s32cc_pll_out_div_t,   \
114a8be748aSGhennadi Procopciuc 	},                                     \
115a8be748aSGhennadi Procopciuc 	.parent = &(PARENT).desc,              \
116a8be748aSGhennadi Procopciuc 	.index = (INDEX),                      \
117a8be748aSGhennadi Procopciuc }
118a8be748aSGhennadi Procopciuc 
11944e2130aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
12044e2130aSGhennadi Procopciuc {                                              \
12144e2130aSGhennadi Procopciuc 	.desc = {                              \
12244e2130aSGhennadi Procopciuc 		.type = s32cc_pll_out_div_t,   \
12344e2130aSGhennadi Procopciuc 	},                                     \
12444e2130aSGhennadi Procopciuc 	.parent = &(PARENT).desc,              \
12544e2130aSGhennadi Procopciuc 	.index = (INDEX),                      \
12644e2130aSGhennadi Procopciuc }
12744e2130aSGhennadi Procopciuc 
128*44ae54afSGhennadi Procopciuc struct s32cc_dfs {
129*44ae54afSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
130*44ae54afSGhennadi Procopciuc 	struct s32cc_clk_obj *parent;
131*44ae54afSGhennadi Procopciuc 	enum s32cc_clk_source instance;
132*44ae54afSGhennadi Procopciuc 	uintptr_t base;
133*44ae54afSGhennadi Procopciuc };
134*44ae54afSGhennadi Procopciuc 
135*44ae54afSGhennadi Procopciuc #define S32CC_DFS_INIT(PARENT, INSTANCE) \
136*44ae54afSGhennadi Procopciuc {                                        \
137*44ae54afSGhennadi Procopciuc 	.desc = {                        \
138*44ae54afSGhennadi Procopciuc 		.type = s32cc_dfs_t,     \
139*44ae54afSGhennadi Procopciuc 	},                               \
140*44ae54afSGhennadi Procopciuc 	.parent = &(PARENT).desc,        \
141*44ae54afSGhennadi Procopciuc 	.instance = (INSTANCE),          \
142*44ae54afSGhennadi Procopciuc }
143*44ae54afSGhennadi Procopciuc 
144*44ae54afSGhennadi Procopciuc struct s32cc_dfs_div {
145*44ae54afSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
146*44ae54afSGhennadi Procopciuc 	struct s32cc_clk_obj *parent;
147*44ae54afSGhennadi Procopciuc 	uint32_t index;
148*44ae54afSGhennadi Procopciuc 	unsigned long freq;
149*44ae54afSGhennadi Procopciuc };
150*44ae54afSGhennadi Procopciuc 
151*44ae54afSGhennadi Procopciuc #define S32CC_DFS_DIV_INIT(PARENT, INDEX) \
152*44ae54afSGhennadi Procopciuc {                                         \
153*44ae54afSGhennadi Procopciuc 	.desc = {                         \
154*44ae54afSGhennadi Procopciuc 		.type = s32cc_dfs_div_t,  \
155*44ae54afSGhennadi Procopciuc 	},                                \
156*44ae54afSGhennadi Procopciuc 	.parent = &(PARENT).desc,         \
157*44ae54afSGhennadi Procopciuc 	.index = (INDEX),                 \
158*44ae54afSGhennadi Procopciuc }
159*44ae54afSGhennadi Procopciuc 
16044e2130aSGhennadi Procopciuc struct s32cc_fixed_div {
16144e2130aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
16244e2130aSGhennadi Procopciuc 	struct s32cc_clk_obj *parent;
16344e2130aSGhennadi Procopciuc 	uint32_t rate_div;
16444e2130aSGhennadi Procopciuc };
16544e2130aSGhennadi Procopciuc 
16644e2130aSGhennadi Procopciuc #define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
16744e2130aSGhennadi Procopciuc {                                              \
16844e2130aSGhennadi Procopciuc 	.desc = {                              \
16944e2130aSGhennadi Procopciuc 		.type = s32cc_fixed_div_t,     \
17044e2130aSGhennadi Procopciuc 	},                                     \
17144e2130aSGhennadi Procopciuc 	.parent = &(PARENT).desc,              \
17244e2130aSGhennadi Procopciuc 	.rate_div = (RATE_DIV),                \
17344e2130aSGhennadi Procopciuc }
17444e2130aSGhennadi Procopciuc 
1757c36209bSGhennadi Procopciuc struct s32cc_clk {
1767c36209bSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
1777c36209bSGhennadi Procopciuc 	struct s32cc_clk_obj *module;
1787c36209bSGhennadi Procopciuc 	struct s32cc_clk *pclock;
1797c36209bSGhennadi Procopciuc 	unsigned long min_freq;
1807c36209bSGhennadi Procopciuc 	unsigned long max_freq;
1817c36209bSGhennadi Procopciuc };
1827c36209bSGhennadi Procopciuc 
1837c36209bSGhennadi Procopciuc struct s32cc_clk_array {
1847c36209bSGhennadi Procopciuc 	unsigned long type_mask;
1857c36209bSGhennadi Procopciuc 	struct s32cc_clk **clks;
1867c36209bSGhennadi Procopciuc 	size_t n_clks;
1877c36209bSGhennadi Procopciuc };
1887c36209bSGhennadi Procopciuc 
189*44ae54afSGhennadi Procopciuc #define S32CC_FREQ_CLK(PARENT_MODULE, PARENT, MIN_F, MAX_F) \
1907c36209bSGhennadi Procopciuc {                                                           \
1917c36209bSGhennadi Procopciuc 	.desc = {                                           \
1927c36209bSGhennadi Procopciuc 		.type = s32cc_clk_t,                        \
1937c36209bSGhennadi Procopciuc 	},                                                  \
194*44ae54afSGhennadi Procopciuc 	.pclock = (PARENT),                                 \
195*44ae54afSGhennadi Procopciuc 	.module = (PARENT_MODULE),                          \
1967c36209bSGhennadi Procopciuc 	.min_freq = (MIN_F),                                \
1977c36209bSGhennadi Procopciuc 	.max_freq = (MAX_F),                                \
1987c36209bSGhennadi Procopciuc }
1997c36209bSGhennadi Procopciuc 
2007c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
201*44ae54afSGhennadi Procopciuc 	S32CC_FREQ_CLK(&(PARENT_MODULE).desc, NULL, MIN_F, MAX_F)
2027c36209bSGhennadi Procopciuc 
2037c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \
2047c36209bSGhennadi Procopciuc 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
2057c36209bSGhennadi Procopciuc 
206*44ae54afSGhennadi Procopciuc #define S32CC_CHILD_CLK(PARENT, MIN_F, MAX_F) \
207*44ae54afSGhennadi Procopciuc 	S32CC_FREQ_CLK(NULL, &(PARENT), MIN_F, MAX_F)
208*44ae54afSGhennadi Procopciuc 
209d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
210d9373519SGhennadi Procopciuc {
211d9373519SGhennadi Procopciuc 	uintptr_t osc_addr;
212d9373519SGhennadi Procopciuc 
213d9373519SGhennadi Procopciuc 	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
214d9373519SGhennadi Procopciuc 	return (struct s32cc_osc *)osc_addr;
215d9373519SGhennadi Procopciuc }
216d9373519SGhennadi Procopciuc 
217d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
218d9373519SGhennadi Procopciuc {
219d9373519SGhennadi Procopciuc 	uintptr_t clk_addr;
220d9373519SGhennadi Procopciuc 
221d9373519SGhennadi Procopciuc 	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
222d9373519SGhennadi Procopciuc 	return (struct s32cc_clk *)clk_addr;
223d9373519SGhennadi Procopciuc }
224d9373519SGhennadi Procopciuc 
22512e7a2cdSGhennadi Procopciuc static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
22612e7a2cdSGhennadi Procopciuc {
22712e7a2cdSGhennadi Procopciuc 	const struct s32cc_clk_obj *module;
22812e7a2cdSGhennadi Procopciuc 
22912e7a2cdSGhennadi Procopciuc 	module = clk->module;
23012e7a2cdSGhennadi Procopciuc 	if (module == NULL) {
23112e7a2cdSGhennadi Procopciuc 		return false;
23212e7a2cdSGhennadi Procopciuc 	}
23312e7a2cdSGhennadi Procopciuc 
2343fa91a94SGhennadi Procopciuc 	return (module->type == s32cc_clkmux_t) ||
2353fa91a94SGhennadi Procopciuc 	    (module->type == s32cc_shared_clkmux_t);
23612e7a2cdSGhennadi Procopciuc }
23712e7a2cdSGhennadi Procopciuc 
23812e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
23912e7a2cdSGhennadi Procopciuc {
24012e7a2cdSGhennadi Procopciuc 	uintptr_t cmux_addr;
24112e7a2cdSGhennadi Procopciuc 
24212e7a2cdSGhennadi Procopciuc 	cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
24312e7a2cdSGhennadi Procopciuc 	return (struct s32cc_clkmux *)cmux_addr;
24412e7a2cdSGhennadi Procopciuc }
24512e7a2cdSGhennadi Procopciuc 
24612e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
24712e7a2cdSGhennadi Procopciuc {
24812e7a2cdSGhennadi Procopciuc 	if (!is_s32cc_clk_mux(clk)) {
24912e7a2cdSGhennadi Procopciuc 		return NULL;
25012e7a2cdSGhennadi Procopciuc 	}
25112e7a2cdSGhennadi Procopciuc 
25212e7a2cdSGhennadi Procopciuc 	return s32cc_obj2clkmux(clk->module);
25312e7a2cdSGhennadi Procopciuc }
25412e7a2cdSGhennadi Procopciuc 
2557ad4e231SGhennadi Procopciuc static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
2567ad4e231SGhennadi Procopciuc {
2577ad4e231SGhennadi Procopciuc 	uintptr_t pll_addr;
2587ad4e231SGhennadi Procopciuc 
2597ad4e231SGhennadi Procopciuc 	pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
2607ad4e231SGhennadi Procopciuc 	return (struct s32cc_pll *)pll_addr;
2617ad4e231SGhennadi Procopciuc }
2627ad4e231SGhennadi Procopciuc 
263de950ef0SGhennadi Procopciuc static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
264de950ef0SGhennadi Procopciuc {
265de950ef0SGhennadi Procopciuc 	uintptr_t plldiv_addr;
266de950ef0SGhennadi Procopciuc 
267de950ef0SGhennadi Procopciuc 	plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
268de950ef0SGhennadi Procopciuc 	return (struct s32cc_pll_out_div *)plldiv_addr;
269de950ef0SGhennadi Procopciuc }
270de950ef0SGhennadi Procopciuc 
27165739db2SGhennadi Procopciuc static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
27265739db2SGhennadi Procopciuc {
27365739db2SGhennadi Procopciuc 	uintptr_t fdiv_addr;
27465739db2SGhennadi Procopciuc 
27565739db2SGhennadi Procopciuc 	fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
27665739db2SGhennadi Procopciuc 	return (struct s32cc_fixed_div *)fdiv_addr;
27765739db2SGhennadi Procopciuc }
27865739db2SGhennadi Procopciuc 
279*44ae54afSGhennadi Procopciuc static inline struct s32cc_dfs *s32cc_obj2dfs(const struct s32cc_clk_obj *mod)
280*44ae54afSGhennadi Procopciuc {
281*44ae54afSGhennadi Procopciuc 	uintptr_t dfs_addr;
282*44ae54afSGhennadi Procopciuc 
283*44ae54afSGhennadi Procopciuc 	dfs_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs, desc);
284*44ae54afSGhennadi Procopciuc 	return (struct s32cc_dfs *)dfs_addr;
285*44ae54afSGhennadi Procopciuc }
286*44ae54afSGhennadi Procopciuc 
287*44ae54afSGhennadi Procopciuc static inline struct s32cc_dfs_div *s32cc_obj2dfsdiv(const struct s32cc_clk_obj *mod)
288*44ae54afSGhennadi Procopciuc {
289*44ae54afSGhennadi Procopciuc 	uintptr_t dfs_div_addr;
290*44ae54afSGhennadi Procopciuc 
291*44ae54afSGhennadi Procopciuc 	dfs_div_addr = ((uintptr_t)mod) - offsetof(struct s32cc_dfs_div, desc);
292*44ae54afSGhennadi Procopciuc 	return (struct s32cc_dfs_div *)dfs_div_addr;
293*44ae54afSGhennadi Procopciuc }
294*44ae54afSGhennadi Procopciuc 
2957c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */
296