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 */
clk_get_name(struct clk * clk)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_is_enabled - Informative state on the clock
136 *
137 * This function is useful during specific system sequences where core
138 * executes atomically (primary core boot, some low power sequences).
139 *
140 * @clk: Clock refernece
141 */
142 bool clk_is_enabled(struct clk *clk);
143
144 /**
145 * clk_get_parent - Get the current clock parent
146 *
147 * @clk: Clock for which the parent is needed
148 * Return the clock parent or NULL if there is no parent
149 */
150 struct clk *clk_get_parent(struct clk *clk);
151
152 /**
153 * clk_get_num_parents - Get the number of parents for a clock
154 *
155 * @clk: Clock for which the number of parents is needed
156 * Return the number of parents
157 */
clk_get_num_parents(struct clk * clk)158 static inline size_t clk_get_num_parents(struct clk *clk)
159 {
160 return clk->num_parents;
161 }
162
163 /**
164 * Get a clock parent by its index
165 *
166 * @clk: Clock for which the parent is needed
167 * @pidx: Parent index for the clock
168 * Return the clock parent at index @pidx or NULL if out of bound
169 */
170 struct clk *clk_get_parent_by_index(struct clk *clk, size_t pidx);
171
172 /**
173 * clk_set_parent - Set the current clock parent
174 *
175 * @clk: Clock for which the parent should be set
176 * @parent: Parent clock to set
177 * Return a TEE_Result compliant value
178 */
179 TEE_Result clk_set_parent(struct clk *clk, struct clk *parent);
180
181 #endif /* __DRIVERS_CLK_H */
182