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