xref: /optee_os/core/include/drivers/clk.h (revision 8fbc005673cdc5af2100277a45ea5b27d914609a)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Bootlin
4  */
5 
6 #ifndef __DRIVERS_CLK_H
7 #define __DRIVERS_CLK_H
8 
9 #include <kernel/refcount.h>
10 #include <stdint.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13 
14 /* Flags for clock */
15 #define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
16 #define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
17 #define CLK_DUTY_CYCLE_PARENT	BIT(2) /* forward duty cycle call to parent */
18 #define CLK_SET_RATE_PARENT	BIT(3) /* propagate rate change up to parent */
19 #define CLK_SET_RATE_UNGATE	BIT(4) /* clock needs to run to set rate */
20 
21 /**
22  * struct clk - Clock structure
23  *
24  * @name: Clock name
25  * @priv: Private data for the clock provider
26  * @ops: Clock operations
27  * @parent: Current parent
28  * @rate: Current clock rate (cached after init or rate change)
29  * @flags: Specific clock flags
30  * @enabled_count: Enable/disable reference counter
31  * @num_parents: Number of parents
32  * @parents: Array of possible parents of the clock
33  * @link: Link the clock list
34  */
35 struct clk {
36 	const char *name;
37 	void *priv;
38 	const struct clk_ops *ops;
39 	struct clk *parent;
40 	unsigned long rate;
41 	unsigned int flags;
42 	struct refcount enabled_count;
43 #ifdef CFG_DRIVERS_CLK_PRINT_TREE
44 	SLIST_ENTRY(clk) link;
45 #endif
46 	size_t num_parents;
47 	struct clk *parents[];
48 };
49 
50 /**
51  * struct clk_duty_cycle - Encoding the duty cycle ratio of a clock
52  *
53  * @num:	Numerator of the duty cycle ratio
54  * @den:	Denominator of the duty cycle ratio
55  */
56 struct clk_duty_cycle {
57 	unsigned int num;
58 	unsigned int den;
59 };
60 
61 /**
62  * struct clk_ops
63  *
64  * @enable: Enable the clock
65  * @disable: Disable the clock
66  * @set_parent: Set the clock parent based on index
67  * @get_parent: Get the current parent index of the clock
68  * @set_rate: Set the clock rate
69  * @get_rate: Get the clock rate
70  * @get_rates_array: Get the supported clock rates as array
71  * @get_rates_steps: Get support clock rates by min/max/step representation
72  * @get_duty_cycle: Get duty cytcle of the clock
73  */
74 struct clk_ops {
75 	TEE_Result (*enable)(struct clk *clk);
76 	void (*disable)(struct clk *clk);
77 	TEE_Result (*set_parent)(struct clk *clk, size_t index);
78 	size_t (*get_parent)(struct clk *clk);
79 	TEE_Result (*set_rate)(struct clk *clk, unsigned long rate,
80 			       unsigned long parent_rate);
81 	unsigned long (*get_rate)(struct clk *clk,
82 				  unsigned long parent_rate);
83 	TEE_Result (*get_rates_array)(struct clk *clk, size_t start_index,
84 				      unsigned long *rates, size_t *nb_elts);
85 	TEE_Result (*get_rates_steps)(struct clk *clk, unsigned long *min,
86 				      unsigned long *max, unsigned long *step);
87 	TEE_Result (*get_duty_cycle)(struct clk *clk,
88 				     struct clk_duty_cycle *duty_cycle);
89 };
90 
91 /**
92  * Return the clock name
93  *
94  * @clk: Clock for which the name is needed
95  * Return a const char * pointing to the clock name
96  */
97 static inline const char *clk_get_name(struct clk *clk)
98 {
99 	return clk->name;
100 }
101 
102 /**
103  * clk_alloc - Allocate a clock structure
104  *
105  * @name: Clock name
106  * @ops: Clock operations
107  * @parent_clks: Parents of the clock
108  * @parent_count: Number of parents of the clock
109  *
110  * Return a clock struct properly initialized or NULL if allocation failed
111  */
112 struct clk *clk_alloc(const char *name, const struct clk_ops *ops,
113 		      struct clk **parent_clks, size_t parent_count);
114 
115 /**
116  * clk_free - Free a clock structure
117  *
118  * @clk: Clock to be freed or NULL
119  */
120 void clk_free(struct clk *clk);
121 
122 /**
123  * clk_register - Register a clock within the clock framework
124  *
125  * @clk: Clock struct to be registered
126  * Return a TEE_Result compliant value
127  */
128 TEE_Result clk_register(struct clk *clk);
129 
130 /**
131  * clk_get_rate - Get clock rate
132  *
133  * @clk: Clock for which the rate is needed
134  * Return the clock rate in Hz
135  */
136 unsigned long clk_get_rate(struct clk *clk);
137 
138 /**
139  * clk_set_rate - Set a clock rate
140  *
141  * @clk: Clock to be set with the rate
142  * @rate: Rate to set in Hz
143  * Return a TEE_Result compliant value
144  */
145 TEE_Result clk_set_rate(struct clk *clk, unsigned long rate);
146 
147 /**
148  * clk_enable - Enable a clock and its ascendance
149  *
150  * @clk: Clock to be enabled
151  * Return a TEE_Result compliant value
152  */
153 TEE_Result clk_enable(struct clk *clk);
154 
155 /**
156  * clk_disable - Disable a clock
157  *
158  * @clk: Clock to be disabled
159  */
160 void clk_disable(struct clk *clk);
161 
162 /**
163  * clk_is_enabled - Informative state on the clock
164  *
165  * This function is useful during specific system sequences where core
166  * executes atomically (primary core boot, some low power sequences).
167  *
168  * @clk: Clock refernece
169  */
170 bool clk_is_enabled(struct clk *clk);
171 
172 /**
173  * clk_get_parent - Get the current clock parent
174  *
175  * @clk: Clock for which the parent is needed
176  * Return the clock parent or NULL if there is no parent
177  */
178 struct clk *clk_get_parent(struct clk *clk);
179 
180 /**
181  * clk_get_num_parents - Get the number of parents for a clock
182  *
183  * @clk: Clock for which the number of parents is needed
184  * Return the number of parents
185  */
186 static inline size_t clk_get_num_parents(struct clk *clk)
187 {
188 	return clk->num_parents;
189 }
190 
191 /**
192  * Get a clock parent by its index
193  *
194  * @clk: Clock for which the parent is needed
195  * @pidx: Parent index for the clock
196  * Return the clock parent at index @pidx or NULL if out of bound
197  */
198 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
199 
200 /**
201  * clk_set_parent - Set the current clock parent
202  *
203  * @clk: Clock for which the parent should be set
204  * @parent: Parent clock to set
205  * Return a TEE_Result compliant value
206  */
207 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
208 
209 /**
210  * clk_get_rates_array - Get supported rates as an array
211  *
212  * @clk: Clock for which the rates are requested
213  * @start_index: start index of requested rates
214  * @rates: Array of rates allocated by caller or NULL to query count of rates
215  * @nb_elts: Max number of elements that the array can hold as input. Contains
216  * the number of elements that was added in the array as output.
217  * Returns a TEE_Result compliant value
218  */
219 TEE_Result clk_get_rates_array(struct clk *clk, size_t start_index,
220 			       unsigned long *rates, size_t *nb_elts);
221 
222 /**
223  * clk_get_rates_steps - Get supported rates as min/max/step triplet
224  *
225  * @clk: Clock for which the rates are requested
226  * @min: Output min supported rate in Hz
227  * @max: Output max supported rate in Hz
228  * @step: Output rate step in Hz
229  * Returns a TEE_Result compliant value
230  */
231 TEE_Result clk_get_rates_steps(struct clk *clk, unsigned long *min,
232 			       unsigned long *max, unsigned long *step);
233 
234 /**
235  * clk_get_duty_cycle - Get clock duty cycle
236  *
237  * @clk: Clock for which the duty cycle is requested
238  * @duty: Output duty cycle info
239  * Return a TEE_Result compliant value
240  */
241 TEE_Result clk_get_duty_cycle(struct clk *clk,
242 			      struct clk_duty_cycle *duty_cycle);
243 
244 /* Print current clock tree summary to output console with debug trace level */
245 #ifdef CFG_DRIVERS_CLK
246 void clk_print_tree(void);
247 #else
248 static inline void clk_print_tree(void)
249 {
250 }
251 #endif /* CFG_DRIVERS_CLK */
252 #endif /* __DRIVERS_CLK_H */
253