xref: /optee_os/core/include/drivers/clk.h (revision 2305544b3b9bce764141c863985a7ab44c98657c)
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 <tee_api_types.h>
12 
13 /* Flags for clock */
14 #define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
15 #define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
16 
17 /**
18  * struct clk - Clock structure
19  *
20  * @name: Clock name
21  * @priv: Private data for the clock provider
22  * @ops: Clock operations
23  * @parent: Current parent
24  * @rate: Current clock rate (cached after init or rate change)
25  * @flags: Specific clock flags
26  * @enabled_count: Enable/disable reference counter
27  * @num_parents: Number of parents
28  * @parents: Array of possible parents of the clock
29  */
30 struct clk {
31 	const char *name;
32 	void *priv;
33 	const struct clk_ops *ops;
34 	struct clk *parent;
35 	unsigned long rate;
36 	unsigned int flags;
37 	struct refcount enabled_count;
38 	size_t num_parents;
39 	struct clk *parents[];
40 };
41 
42 /**
43  * struct clk_ops
44  *
45  * @enable: Enable the clock
46  * @disable: Disable the clock
47  * @set_parent: Set the clock parent based on index
48  * @get_parent: Get the current parent index of the clock
49  * @set_rate: Set the clock rate
50  * @get_rate: Get the clock rate
51  */
52 struct clk_ops {
53 	TEE_Result (*enable)(struct clk *clk);
54 	void (*disable)(struct clk *clk);
55 	TEE_Result (*set_parent)(struct clk *clk, size_t index);
56 	size_t (*get_parent)(struct clk *clk);
57 	TEE_Result (*set_rate)(struct clk *clk, unsigned long rate,
58 			       unsigned long parent_rate);
59 	unsigned long (*get_rate)(struct clk *clk,
60 				  unsigned long parent_rate);
61 };
62 
63 /**
64  * Return the clock name
65  *
66  * @clk: Clock for which the name is needed
67  * Return a const char * pointing to the clock name
68  */
69 static inline const char *clk_get_name(struct clk *clk)
70 {
71 	return clk->name;
72 }
73 
74 /**
75  * clk_alloc - Allocate a clock structure
76  *
77  * @name: Clock name
78  * @ops: Clock operations
79  * @parent_clks: Parents of the clock
80  * @parent_count: Number of parents of the clock
81  *
82  * Return a clock struct properly initialized or NULL if allocation failed
83  */
84 struct clk *clk_alloc(const char *name, const struct clk_ops *ops,
85 		      struct clk **parent_clks, size_t parent_count);
86 
87 /**
88  * clk_free - Free a clock structure
89  *
90  * @clk: Clock to be freed or NULL
91  */
92 void clk_free(struct clk *clk);
93 
94 /**
95  * clk_register - Register a clock within the clock framework
96  *
97  * @clk: Clock struct to be registered
98  * Return a TEE_Result compliant value
99  */
100 TEE_Result clk_register(struct clk *clk);
101 
102 /**
103  * clk_get_rate - Get clock rate
104  *
105  * @clk: Clock for which the rate is needed
106  * Return the clock rate in Hz
107  */
108 unsigned long clk_get_rate(struct clk *clk);
109 
110 /**
111  * clk_set_rate - Set a clock rate
112  *
113  * @clk: Clock to be set with the rate
114  * @rate: Rate to set in Hz
115  * Return a TEE_Result compliant value
116  */
117 TEE_Result clk_set_rate(struct clk *clk, unsigned long rate);
118 
119 /**
120  * clk_enable - Enable a clock and its ascendance
121  *
122  * @clk: Clock to be enabled
123  * Return a TEE_Result compliant value
124  */
125 TEE_Result clk_enable(struct clk *clk);
126 
127 /**
128  * clk_disable - Disable a clock
129  *
130  * @clk: Clock to be disabled
131  */
132 void clk_disable(struct clk *clk);
133 
134 /**
135  * clk_get_parent - Get the current clock parent
136  *
137  * @clk: Clock for which the parent is needed
138  * Return the clock parent or NULL if there is no parent
139  */
140 struct clk *clk_get_parent(struct clk *clk);
141 
142 /**
143  * clk_get_num_parents - Get the number of parents for a clock
144  *
145  * @clk: Clock for which the number of parents is needed
146  * Return the number of parents
147  */
148 static inline size_t clk_get_num_parents(struct clk *clk)
149 {
150 	return clk->num_parents;
151 }
152 
153 /**
154  * Get a clock parent by its index
155  *
156  * @clk: Clock for which the parent is needed
157  * @pidx: Parent index for the clock
158  * Return the clock parent at index @pidx or NULL if out of bound
159  */
160 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
161 
162 /**
163  * clk_set_parent - Set the current clock parent
164  *
165  * @clk: Clock for which the parent should be set
166  * @parent: Parent clock to set
167  * Return a TEE_Result compliant value
168  */
169 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
170 
171 #endif /* __DRIVERS_CLK_H */
172