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