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