1 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
2 /*
3  * Copyright (C) STMicroelectronics 2022 - All Rights Reserved
4  */
5 
6 #ifndef CLK_STM32_CORE_H
7 #define CLK_STM32_CORE_H
8 
9 #include <drivers/clk.h>
10 
11 struct mux_cfg {
12 	uint16_t offset;
13 	uint8_t shift;
14 	uint8_t width;
15 	uint8_t ready;
16 };
17 
18 struct gate_cfg {
19 	uint16_t offset;
20 	uint8_t bit_idx;
21 	uint8_t set_clr;
22 };
23 
24 struct div_table_cfg {
25 	unsigned int val;
26 	unsigned int div;
27 };
28 
29 struct div_cfg {
30 	uint16_t offset;
31 	uint8_t shift;
32 	uint8_t width;
33 	uint8_t flags;
34 	uint8_t ready;
35 	const struct div_table_cfg *table;
36 };
37 
38 struct clk_stm32_priv {
39 	uintptr_t base;
40 	size_t nb_clk_refs;
41 	struct clk **clk_refs;
42 	const struct mux_cfg *muxes;
43 	const uint32_t nb_muxes;
44 	const struct gate_cfg *gates;
45 	uint8_t *gate_cpt;
46 	const uint32_t nb_gates;
47 	const struct div_cfg *div;
48 	const uint32_t nb_div;
49 	bool (*is_critical)(struct clk *clk);
50 	void *pdata;
51 };
52 
53 struct clk_fixed_rate_cfg {
54 	unsigned long rate;
55 };
56 
57 struct fixed_factor_cfg {
58 	unsigned int mult;
59 	unsigned int div;
60 };
61 
62 struct clk_gate_cfg {
63 	uint32_t offset;
64 	uint8_t bit_idx;
65 };
66 
67 struct clk_stm32_mux_cfg {
68 	int mux_id;
69 };
70 
71 struct clk_stm32_gate_cfg {
72 	int gate_id;
73 };
74 
75 struct clk_stm32_div_cfg {
76 	int div_id;
77 };
78 
79 struct clk_stm32_composite_cfg {
80 	int gate_id;
81 	int div_id;
82 	int mux_id;
83 };
84 
85 struct clk_stm32_timer_cfg {
86 	uint32_t apbdiv;
87 	uint32_t timpre;
88 };
89 
90 struct clk_stm32_gate_ready_cfg {
91 	int gate_id;
92 	int gate_rdy_id;
93 };
94 
95 /* Define for divider clocks */
96 #define CLK_DIVIDER_ONE_BASED		BIT(0)
97 #define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
98 #define CLK_DIVIDER_ALLOW_ZERO		BIT(2)
99 #define CLK_DIVIDER_HIWORD_MASK		BIT(3)
100 #define CLK_DIVIDER_ROUND_CLOSEST	BIT(4)
101 #define CLK_DIVIDER_READ_ONLY		BIT(5)
102 #define CLK_DIVIDER_MAX_AT_ZERO		BIT(6)
103 #define CLK_DIVIDER_BIG_ENDIAN		BIT(7)
104 
105 #define DIV_NO_RDY		UINT8_MAX
106 #define MUX_NO_RDY		UINT8_MAX
107 
108 #define MASK_WIDTH_SHIFT(_width, _shift) \
109 	GENMASK_32(((_width) + (_shift) - 1U), (_shift))
110 
111 /* Define for composite clocks */
112 #define NO_MUX		INT32_MAX
113 #define NO_DIV		INT32_MAX
114 #define NO_GATE		INT32_MAX
115 
116 void stm32_gate_enable(uint16_t gate_id);
117 void stm32_gate_disable(uint16_t gate_id);
118 bool stm32_gate_is_enabled(uint16_t gate_id);
119 TEE_Result stm32_gate_wait_ready(uint16_t gate_id, bool ready_on);
120 TEE_Result stm32_gate_rdy_enable(uint16_t gate_id);
121 TEE_Result stm32_gate_rdy_disable(uint16_t gate_id);
122 
123 /*
124  * Set gate to an enable or disable state without updating its
125  * refcount. This is exclusively intended to be used during initialization
126  * where refcount value are 0.
127  */
128 void stm32_gate_set_init_state(uint16_t gate_id, bool enable);
129 
130 size_t stm32_mux_get_parent(uint32_t mux_id);
131 TEE_Result stm32_mux_set_parent(uint16_t pid, uint8_t sel);
132 
133 TEE_Result stm32_div_set_rate(int div_id, unsigned long rate,
134 			      unsigned long prate);
135 
136 uint32_t stm32_div_get_value(int div_id);
137 TEE_Result stm32_div_set_value(uint32_t div_id, uint32_t value);
138 
139 int clk_stm32_parse_fdt_by_name(const void *fdt, int node, const char *name,
140 				uint32_t *tab, uint32_t *nb);
141 
142 unsigned long clk_stm32_divider_get_rate(struct clk *clk,
143 					 unsigned long parent_rate);
144 
145 TEE_Result clk_stm32_divider_set_rate(struct clk *clk,
146 				      unsigned long rate,
147 				      unsigned long parent_rate);
148 
149 size_t clk_stm32_composite_get_parent(struct clk *clk);
150 TEE_Result clk_stm32_composite_set_parent(struct clk *clk, size_t pidx);
151 unsigned long clk_stm32_composite_get_rate(struct clk *clk,
152 					   unsigned long parent_rate);
153 TEE_Result clk_stm32_composite_set_rate(struct clk *clk, unsigned long rate,
154 					unsigned long parent_rate);
155 TEE_Result clk_stm32_composite_gate_enable(struct clk *clk);
156 void clk_stm32_composite_gate_disable(struct clk *clk);
157 
158 TEE_Result clk_stm32_set_parent_by_index(struct clk *clk, size_t pidx);
159 
160 extern const struct clk_ops clk_fixed_factor_ops;
161 extern const struct clk_ops clk_fixed_clk_ops;
162 extern const struct clk_ops clk_stm32_gate_ops;
163 extern const struct clk_ops clk_stm32_gate_ready_ops;
164 extern const struct clk_ops clk_stm32_divider_ops;
165 extern const struct clk_ops clk_stm32_mux_ops;
166 extern const struct clk_ops clk_stm32_composite_ops;
167 
168 #define PARENT(x...) { x }
169 
170 #define STM32_FIXED_RATE(_name, _rate)\
171 	struct clk _name = {\
172 		.ops = &clk_fixed_clk_ops,\
173 		.priv = &(struct clk_fixed_rate_cfg) {\
174 			.rate = (_rate),\
175 		},\
176 		.name = #_name,\
177 		.flags = 0,\
178 		.num_parents = 0,\
179 	}
180 
181 #define STM32_FIXED_FACTOR(_name, _parent, _flags, _mult, _div)\
182 	struct clk _name = {\
183 		.ops = &clk_fixed_factor_ops,\
184 		.priv = &(struct fixed_factor_cfg) {\
185 			.mult = _mult,\
186 			.div = _div,\
187 		},\
188 		.name = #_name,\
189 		.flags = (_flags),\
190 		.num_parents = 1,\
191 		.parents = { (_parent) },\
192 	}
193 
194 #define STM32_GATE(_name, _parent, _flags, _gate_id)\
195 	struct clk _name = {\
196 		.ops = &clk_stm32_gate_ops,\
197 		.priv = &(struct clk_stm32_gate_cfg) {\
198 			.gate_id = _gate_id,\
199 		},\
200 		.name = #_name,\
201 		.flags = (_flags),\
202 		.num_parents = 1,\
203 		.parents = { (_parent) },\
204 	}
205 
206 #define STM32_DIVIDER(_name, _parent, _flags, _div_id)\
207 	struct clk _name = {\
208 		.ops = &clk_stm32_divider_ops,\
209 		.priv = &(struct clk_stm32_div_cfg) {\
210 			.div_id = (_div_id),\
211 		},\
212 		.name = #_name,\
213 		.flags = (_flags),\
214 		.num_parents = 1,\
215 		.parents = { (_parent) },\
216 	}
217 
218 #define STM32_MUX(_name, _nb_parents, _parents, _flags, _mux_id)\
219 	struct clk _name = {\
220 		.ops = &clk_stm32_mux_ops,\
221 		.priv = &(struct clk_stm32_mux_cfg) {\
222 			.mux_id = (_mux_id),\
223 		},\
224 		.name = #_name,\
225 		.flags = (_flags),\
226 		.num_parents = (_nb_parents),\
227 		.parents = _parents,\
228 	}
229 
230 #define STM32_GATE_READY(_name, _parent, _flags, _gate_id)\
231 	struct clk _name = {\
232 		.ops = &clk_stm32_gate_ready_ops,\
233 		.priv = &(struct clk_stm32_gate_cfg) {\
234 			.gate_id = _gate_id,\
235 		},\
236 		.name = #_name,\
237 		.flags = (_flags),\
238 		.num_parents = 1,\
239 		.parents = { _parent },\
240 	}
241 
242 #define STM32_COMPOSITE(_name, _nb_parents, _parents, _flags,\
243 			_gate_id, _div_id, _mux_id)\
244 	struct clk _name = {\
245 		.ops = &clk_stm32_composite_ops,\
246 		.priv = &(struct clk_stm32_composite_cfg) {\
247 			.gate_id = (_gate_id),\
248 			.div_id = (_div_id),\
249 			.mux_id = (_mux_id),\
250 		},\
251 		.name = #_name,\
252 		.flags = (_flags),\
253 		.num_parents = (_nb_parents),\
254 		.parents = _parents,\
255 	}
256 
257 struct clk_stm32_priv *clk_stm32_get_priv(void);
258 uintptr_t clk_stm32_get_rcc_base(void);
259 
260 TEE_Result clk_stm32_init(struct clk_stm32_priv *priv, uintptr_t base);
261 
262 void stm32mp_clk_provider_probe_final(const void *fdt, int node,
263 				      struct clk_stm32_priv *priv);
264 
265 #endif /* CLK_STM32_CORE_H */
266