xref: /rk3399_ARM-atf/include/drivers/nxp/clk/s32cc/s32cc-clk-modules.h (revision 7ad4e2312f58606ee74ac7c655a655bd85148582)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright 2020-2024 NXP
4  */
5 #ifndef S32CC_CLK_MODULES_H
6 #define S32CC_CLK_MODULES_H
7 
8 #include <inttypes.h>
9 #include <stdbool.h>
10 #include <stddef.h>
11 
12 #define MHZ	UL(1000000)
13 #define GHZ	(UL(1000) * MHZ)
14 
15 enum s32cc_clkm_type {
16 	s32cc_osc_t,
17 	s32cc_clk_t,
18 	s32cc_pll_t,
19 	s32cc_pll_out_div_t,
20 	s32cc_clkmux_t,
21 	s32cc_shared_clkmux_t,
22 };
23 
24 enum s32cc_clk_source {
25 	S32CC_FIRC,
26 	S32CC_FXOSC,
27 	S32CC_SIRC,
28 	S32CC_ARM_PLL,
29 	S32CC_CGM1,
30 };
31 
32 struct s32cc_clk_obj {
33 	enum s32cc_clkm_type type;
34 	uint32_t refcount;
35 };
36 
37 struct s32cc_osc {
38 	struct s32cc_clk_obj desc;
39 	enum s32cc_clk_source source;
40 	unsigned long freq;
41 	void *base;
42 };
43 
44 #define S32CC_OSC_INIT(SOURCE)       \
45 {                                    \
46 	.desc = {                    \
47 		.type = s32cc_osc_t, \
48 	},                           \
49 	.source = (SOURCE),          \
50 }
51 
52 struct s32cc_clkmux {
53 	struct s32cc_clk_obj desc;
54 	enum s32cc_clk_source module;
55 	uint8_t index; /* Mux index in parent module */
56 	unsigned long source_id; /* Selected source */
57 	uint8_t nclks; /* Number of input clocks */
58 	unsigned long clkids[5]; /* IDs of the input clocks */
59 };
60 
61 #define S32CC_CLKMUX_TYPE_INIT(TYPE, MODULE, INDEX, NCLKS, ...) \
62 {                                                               \
63 	.desc = {                                               \
64 		.type = (TYPE),                                 \
65 	},                                                      \
66 	.module = (MODULE),                                     \
67 	.index = (INDEX),                                       \
68 	.nclks = (NCLKS),                                       \
69 	.clkids = {__VA_ARGS__},                                \
70 }
71 
72 #define S32CC_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)     \
73 	S32CC_CLKMUX_TYPE_INIT(s32cc_clkmux_t, MODULE,   \
74 			       INDEX, NCLKS, __VA_ARGS__)
75 
76 #define S32CC_SHARED_CLKMUX_INIT(MODULE, INDEX, NCLKS, ...)   \
77 	S32CC_CLKMUX_TYPE_INIT(s32cc_shared_clkmux_t, MODULE, \
78 			       INDEX, NCLKS, __VA_ARGS__)
79 
80 struct s32cc_pll {
81 	struct s32cc_clk_obj desc;
82 	struct s32cc_clk_obj *source;
83 	enum s32cc_clk_source instance;
84 	unsigned long vco_freq;
85 	uint32_t ndividers;
86 	uintptr_t base;
87 };
88 
89 #define S32CC_PLL_INIT(PLL_MUX_CLK, INSTANCE, NDIVIDERS) \
90 {                                                        \
91 	.desc = {                                        \
92 		.type = s32cc_pll_t,                     \
93 	},                                               \
94 	.source = &(PLL_MUX_CLK).desc,                   \
95 	.instance = (INSTANCE),                          \
96 	.ndividers = (NDIVIDERS),                        \
97 }
98 
99 struct s32cc_pll_out_div {
100 	struct s32cc_clk_obj desc;
101 	struct s32cc_clk_obj *parent;
102 	uint32_t index;
103 	unsigned long freq;
104 };
105 
106 #define S32CC_PLL_OUT_DIV_INIT(PARENT, INDEX)  \
107 {                                              \
108 	.desc = {                              \
109 		.type = s32cc_pll_out_div_t,   \
110 	},                                     \
111 	.parent = &(PARENT).desc,              \
112 	.index = (INDEX),                      \
113 }
114 
115 struct s32cc_clk {
116 	struct s32cc_clk_obj desc;
117 	struct s32cc_clk_obj *module;
118 	struct s32cc_clk *pclock;
119 	unsigned long min_freq;
120 	unsigned long max_freq;
121 };
122 
123 struct s32cc_clk_array {
124 	unsigned long type_mask;
125 	struct s32cc_clk **clks;
126 	size_t n_clks;
127 };
128 
129 #define S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F) \
130 {                                                      \
131 	.desc = {                                      \
132 		.type = s32cc_clk_t,                   \
133 	},                                             \
134 	.module = &(PARENT_MODULE).desc,               \
135 	.min_freq = (MIN_F),                           \
136 	.max_freq = (MAX_F),                           \
137 }
138 
139 #define S32CC_FREQ_MODULE_CLK(PARENT_MODULE, MIN_F, MAX_F) \
140 	S32CC_FREQ_MODULE(PARENT_MODULE, MIN_F, MAX_F)
141 
142 #define S32CC_MODULE_CLK(PARENT_MODULE) \
143 	S32CC_FREQ_MODULE_CLK(PARENT_MODULE, 0, 0)
144 
145 static inline struct s32cc_osc *s32cc_obj2osc(const struct s32cc_clk_obj *mod)
146 {
147 	uintptr_t osc_addr;
148 
149 	osc_addr = ((uintptr_t)mod) - offsetof(struct s32cc_osc, desc);
150 	return (struct s32cc_osc *)osc_addr;
151 }
152 
153 static inline struct s32cc_clk *s32cc_obj2clk(const struct s32cc_clk_obj *mod)
154 {
155 	uintptr_t clk_addr;
156 
157 	clk_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clk, desc);
158 	return (struct s32cc_clk *)clk_addr;
159 }
160 
161 static inline bool is_s32cc_clk_mux(const struct s32cc_clk *clk)
162 {
163 	const struct s32cc_clk_obj *module;
164 
165 	module = clk->module;
166 	if (module == NULL) {
167 		return false;
168 	}
169 
170 	return (module->type == s32cc_clkmux_t) ||
171 	    (module->type == s32cc_shared_clkmux_t);
172 }
173 
174 static inline struct s32cc_clkmux *s32cc_obj2clkmux(const struct s32cc_clk_obj *mod)
175 {
176 	uintptr_t cmux_addr;
177 
178 	cmux_addr = ((uintptr_t)mod) - offsetof(struct s32cc_clkmux, desc);
179 	return (struct s32cc_clkmux *)cmux_addr;
180 }
181 
182 static inline struct s32cc_clkmux *s32cc_clk2mux(const struct s32cc_clk *clk)
183 {
184 	if (!is_s32cc_clk_mux(clk)) {
185 		return NULL;
186 	}
187 
188 	return s32cc_obj2clkmux(clk->module);
189 }
190 
191 static inline struct s32cc_pll *s32cc_obj2pll(const struct s32cc_clk_obj *mod)
192 {
193 	uintptr_t pll_addr;
194 
195 	pll_addr = ((uintptr_t)mod) - offsetof(struct s32cc_pll, desc);
196 	return (struct s32cc_pll *)pll_addr;
197 }
198 
199 #endif /* S32CC_CLK_MODULES_H */
200