xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 65739db28bf0c0d5d4daa8735a2935681f835634)
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,
20a8be748aSGhennadi Procopciuc 	s32cc_clkmux_t,
213fa91a94SGhennadi Procopciuc 	s32cc_shared_clkmux_t,
2244e2130aSGhennadi Procopciuc 	s32cc_fixed_div_t,
237c36209bSGhennadi Procopciuc };
247c36209bSGhennadi Procopciuc 
257c36209bSGhennadi Procopciuc enum s32cc_clk_source {
267c36209bSGhennadi Procopciuc 	S32CC_FIRC,
277c36209bSGhennadi Procopciuc 	S32CC_FXOSC,
287c36209bSGhennadi Procopciuc 	S32CC_SIRC,
29a8be748aSGhennadi Procopciuc 	S32CC_ARM_PLL,
303fa91a94SGhennadi Procopciuc 	S32CC_CGM1,
317c36209bSGhennadi Procopciuc };
327c36209bSGhennadi Procopciuc 
337c36209bSGhennadi Procopciuc struct s32cc_clk_obj {
347c36209bSGhennadi Procopciuc 	enum s32cc_clkm_type type;
357c36209bSGhennadi Procopciuc 	uint32_t refcount;
367c36209bSGhennadi Procopciuc };
377c36209bSGhennadi Procopciuc 
387c36209bSGhennadi Procopciuc struct s32cc_osc {
397c36209bSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
407c36209bSGhennadi Procopciuc 	enum s32cc_clk_source source;
417c36209bSGhennadi Procopciuc 	unsigned long freq;
427c36209bSGhennadi Procopciuc 	void *base;
437c36209bSGhennadi Procopciuc };
447c36209bSGhennadi Procopciuc 
457c36209bSGhennadi Procopciuc #define S32CC_OSC_INIT(SOURCE)       \
467c36209bSGhennadi Procopciuc {                                    \
477c36209bSGhennadi Procopciuc 	.desc = {                    \
487c36209bSGhennadi Procopciuc 		.type = s32cc_osc_t, \
497c36209bSGhennadi Procopciuc 	},                           \
507c36209bSGhennadi Procopciuc 	.source = (SOURCE),          \
517c36209bSGhennadi Procopciuc }
527c36209bSGhennadi Procopciuc 
53a8be748aSGhennadi Procopciuc struct s32cc_clkmux {
54a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
55a8be748aSGhennadi Procopciuc 	enum s32cc_clk_source module;
56a8be748aSGhennadi Procopciuc 	uint8_t index; /* Mux index in parent module */
57a8be748aSGhennadi Procopciuc 	unsigned long source_id; /* Selected source */
58a8be748aSGhennadi Procopciuc 	uint8_t nclks; /* Number of input clocks */
59a8be748aSGhennadi Procopciuc 	unsigned long clkids[5]; /* IDs of the input clocks */
60a8be748aSGhennadi Procopciuc };
61a8be748aSGhennadi Procopciuc 
62a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
63a8be748aSGhennadi Procopciuc {                                                               \
64a8be748aSGhennadi Procopciuc 	.desc = {                                               \
65a8be748aSGhennadi Procopciuc 		.type = (TYPE),                                 \
66a8be748aSGhennadi Procopciuc 	},                                                      \
67a8be748aSGhennadi Procopciuc 	.module = (MODULE),                                     \
68a8be748aSGhennadi Procopciuc 	.index = (INDEX),                                       \
69a8be748aSGhennadi Procopciuc 	.nclks = (NCLKS),                                       \
70a8be748aSGhennadi Procopciuc 	.clkids = {__VA_ARGS__},                                \
71a8be748aSGhennadi Procopciuc }
72a8be748aSGhennadi Procopciuc 
73a8be748aSGhennadi Procopciuc #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
74a8be748aSGhennadi Procopciuc 	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
75a8be748aSGhennadi Procopciuc 			       INDEX, NCLKS, __VA_ARGS__)
76a8be748aSGhennadi Procopciuc 
773fa91a94SGhennadi Procopciuc #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
783fa91a94SGhennadi Procopciuc 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
793fa91a94SGhennadi Procopciuc 			       INDEX, NCLKS, __VA_ARGS__)
803fa91a94SGhennadi Procopciuc 
81a8be748aSGhennadi Procopciuc struct s32cc_pll {
82a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
83a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj *source;
84a8be748aSGhennadi Procopciuc 	enum s32cc_clk_source instance;
85a8be748aSGhennadi Procopciuc 	unsigned long vco_freq;
86a8be748aSGhennadi Procopciuc 	uint32_t ndividers;
87a8be748aSGhennadi Procopciuc 	uintptr_t base;
88a8be748aSGhennadi Procopciuc };
89a8be748aSGhennadi Procopciuc 
90a8be748aSGhennadi Procopciuc #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
91a8be748aSGhennadi Procopciuc {                                                        \
92a8be748aSGhennadi Procopciuc 	.desc = {                                        \
93a8be748aSGhennadi Procopciuc 		.type = s32cc_pll_t,                     \
94a8be748aSGhennadi Procopciuc 	},                                               \
95a8be748aSGhennadi Procopciuc 	.source = &(PLL_MUX_CLK).desc,                   \
96a8be748aSGhennadi Procopciuc 	.instance = (INSTANCE),                          \
97a8be748aSGhennadi Procopciuc 	.ndividers = (NDIVIDERS),                        \
98a8be748aSGhennadi Procopciuc }
99a8be748aSGhennadi Procopciuc 
100a8be748aSGhennadi Procopciuc struct s32cc_pll_out_div {
101a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
102a8be748aSGhennadi Procopciuc 	struct s32cc_clk_obj *parent;
103a8be748aSGhennadi Procopciuc 	uint32_t index;
104a8be748aSGhennadi Procopciuc 	unsigned long freq;
105a8be748aSGhennadi Procopciuc };
106a8be748aSGhennadi Procopciuc 
107a8be748aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
108a8be748aSGhennadi Procopciuc {                                              \
109a8be748aSGhennadi Procopciuc 	.desc = {                              \
110a8be748aSGhennadi Procopciuc 		.type = s32cc_pll_out_div_t,   \
111a8be748aSGhennadi Procopciuc 	},                                     \
112a8be748aSGhennadi Procopciuc 	.parent = &(PARENT).desc,              \
113a8be748aSGhennadi Procopciuc 	.index = (INDEX),                      \
114a8be748aSGhennadi Procopciuc }
115a8be748aSGhennadi Procopciuc 
11644e2130aSGhennadi Procopciuc #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
11744e2130aSGhennadi Procopciuc {                                              \
11844e2130aSGhennadi Procopciuc 	.desc = {                              \
11944e2130aSGhennadi Procopciuc 		.type = s32cc_pll_out_div_t,   \
12044e2130aSGhennadi Procopciuc 	},                                     \
12144e2130aSGhennadi Procopciuc 	.parent = &(PARENT).desc,              \
12244e2130aSGhennadi Procopciuc 	.index = (INDEX),                      \
12344e2130aSGhennadi Procopciuc }
12444e2130aSGhennadi Procopciuc 
12544e2130aSGhennadi Procopciuc struct s32cc_fixed_div {
12644e2130aSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
12744e2130aSGhennadi Procopciuc 	struct s32cc_clk_obj *parent;
12844e2130aSGhennadi Procopciuc 	uint32_t rate_div;
12944e2130aSGhennadi Procopciuc };
13044e2130aSGhennadi Procopciuc 
13144e2130aSGhennadi Procopciuc #define S32CC_FIXED_DIV_INIT(PARENT, RATE_DIV) \
13244e2130aSGhennadi Procopciuc {                                              \
13344e2130aSGhennadi Procopciuc 	.desc = {                              \
13444e2130aSGhennadi Procopciuc 		.type = s32cc_fixed_div_t,     \
13544e2130aSGhennadi Procopciuc 	},                                     \
13644e2130aSGhennadi Procopciuc 	.parent = &(PARENT).desc,              \
13744e2130aSGhennadi Procopciuc 	.rate_div = (RATE_DIV),                \
13844e2130aSGhennadi Procopciuc }
13944e2130aSGhennadi Procopciuc 
1407c36209bSGhennadi Procopciuc struct s32cc_clk {
1417c36209bSGhennadi Procopciuc 	struct s32cc_clk_obj desc;
1427c36209bSGhennadi Procopciuc 	struct s32cc_clk_obj *module;
1437c36209bSGhennadi Procopciuc 	struct s32cc_clk *pclock;
1447c36209bSGhennadi Procopciuc 	unsigned long min_freq;
1457c36209bSGhennadi Procopciuc 	unsigned long max_freq;
1467c36209bSGhennadi Procopciuc };
1477c36209bSGhennadi Procopciuc 
1487c36209bSGhennadi Procopciuc struct s32cc_clk_array {
1497c36209bSGhennadi Procopciuc 	unsigned long type_mask;
1507c36209bSGhennadi Procopciuc 	struct s32cc_clk **clks;
1517c36209bSGhennadi Procopciuc 	size_t n_clks;
1527c36209bSGhennadi Procopciuc };
1537c36209bSGhennadi Procopciuc 
1547c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
1557c36209bSGhennadi Procopciuc {                                                      \
1567c36209bSGhennadi Procopciuc 	.desc = {                                      \
1577c36209bSGhennadi Procopciuc 		.type = s32cc_clk_t,                   \
1587c36209bSGhennadi Procopciuc 	},                                             \
1597c36209bSGhennadi Procopciuc 	.module = &(PARENT_MODULE).desc,               \
1607c36209bSGhennadi Procopciuc 	.min_freq = (MIN_F),                           \
1617c36209bSGhennadi Procopciuc 	.max_freq = (MAX_F),                           \
1627c36209bSGhennadi Procopciuc }
1637c36209bSGhennadi Procopciuc 
1647c36209bSGhennadi Procopciuc #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
1657c36209bSGhennadi Procopciuc 	S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
1667c36209bSGhennadi Procopciuc 
1677c36209bSGhennadi Procopciuc #define S32CC_MODULE_CLK(PARENT_MODULE) \
1687c36209bSGhennadi Procopciuc 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
1697c36209bSGhennadi Procopciuc 
170d9373519SGhennadi Procopciuc static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
171d9373519SGhennadi Procopciuc {
172d9373519SGhennadi Procopciuc 	uintptr_t osc_addr;
173d9373519SGhennadi Procopciuc 
174d9373519SGhennadi Procopciuc 	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
175d9373519SGhennadi Procopciuc 	return (struct s32cc_osc *)osc_addr;
176d9373519SGhennadi Procopciuc }
177d9373519SGhennadi Procopciuc 
178d9373519SGhennadi Procopciuc static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
179d9373519SGhennadi Procopciuc {
180d9373519SGhennadi Procopciuc 	uintptr_t clk_addr;
181d9373519SGhennadi Procopciuc 
182d9373519SGhennadi Procopciuc 	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
183d9373519SGhennadi Procopciuc 	return (struct s32cc_clk *)clk_addr;
184d9373519SGhennadi Procopciuc }
185d9373519SGhennadi Procopciuc 
18612e7a2cdSGhennadi Procopciuc static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
18712e7a2cdSGhennadi Procopciuc {
18812e7a2cdSGhennadi Procopciuc 	const struct s32cc_clk_obj *module;
18912e7a2cdSGhennadi Procopciuc 
19012e7a2cdSGhennadi Procopciuc 	module = clk->module;
19112e7a2cdSGhennadi Procopciuc 	if (module == NULL) {
19212e7a2cdSGhennadi Procopciuc 		return false;
19312e7a2cdSGhennadi Procopciuc 	}
19412e7a2cdSGhennadi Procopciuc 
1953fa91a94SGhennadi Procopciuc 	return (module->type == s32cc_clkmux_t) ||
1963fa91a94SGhennadi Procopciuc 	    (module->type == s32cc_shared_clkmux_t);
19712e7a2cdSGhennadi Procopciuc }
19812e7a2cdSGhennadi Procopciuc 
19912e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
20012e7a2cdSGhennadi Procopciuc {
20112e7a2cdSGhennadi Procopciuc 	uintptr_t cmux_addr;
20212e7a2cdSGhennadi Procopciuc 
20312e7a2cdSGhennadi Procopciuc 	cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
20412e7a2cdSGhennadi Procopciuc 	return (struct s32cc_clkmux *)cmux_addr;
20512e7a2cdSGhennadi Procopciuc }
20612e7a2cdSGhennadi Procopciuc 
20712e7a2cdSGhennadi Procopciuc static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
20812e7a2cdSGhennadi Procopciuc {
20912e7a2cdSGhennadi Procopciuc 	if (!is_s32cc_clk_mux(clk)) {
21012e7a2cdSGhennadi Procopciuc 		return NULL;
21112e7a2cdSGhennadi Procopciuc 	}
21212e7a2cdSGhennadi Procopciuc 
21312e7a2cdSGhennadi Procopciuc 	return s32cc_obj2clkmux(clk->module);
21412e7a2cdSGhennadi Procopciuc }
21512e7a2cdSGhennadi Procopciuc 
2167ad4e231SGhennadi Procopciuc static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
2177ad4e231SGhennadi Procopciuc {
2187ad4e231SGhennadi Procopciuc 	uintptr_t pll_addr;
2197ad4e231SGhennadi Procopciuc 
2207ad4e231SGhennadi Procopciuc 	pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
2217ad4e231SGhennadi Procopciuc 	return (struct s32cc_pll *)pll_addr;
2227ad4e231SGhennadi Procopciuc }
2237ad4e231SGhennadi Procopciuc 
224de950ef0SGhennadi Procopciuc static inline struct s32cc_pll_out_div *s32cc_obj2plldiv(const struct s32cc_clk_obj *mod)
225de950ef0SGhennadi Procopciuc {
226de950ef0SGhennadi Procopciuc 	uintptr_t plldiv_addr;
227de950ef0SGhennadi Procopciuc 
228de950ef0SGhennadi Procopciuc 	plldiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll_out_div, desc);
229de950ef0SGhennadi Procopciuc 	return (struct s32cc_pll_out_div *)plldiv_addr;
230de950ef0SGhennadi Procopciuc }
231de950ef0SGhennadi Procopciuc 
232*65739db2SGhennadi Procopciuc static inline struct s32cc_fixed_div *s32cc_obj2fixeddiv(const struct s32cc_clk_obj *mod)
233*65739db2SGhennadi Procopciuc {
234*65739db2SGhennadi Procopciuc 	uintptr_t fdiv_addr;
235*65739db2SGhennadi Procopciuc 
236*65739db2SGhennadi Procopciuc 	fdiv_addr = ((uintptr_t)mod) - offsetof(struct s32cc_fixed_div, desc);
237*65739db2SGhennadi Procopciuc 	return (struct s32cc_fixed_div *)fdiv_addr;
238*65739db2SGhennadi Procopciuc }
239*65739db2SGhennadi Procopciuc 
2407c36209bSGhennadi Procopciuc #endif /* S32CC_CLK_MODULES_H */
241