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