xref: /OK3568_Linux_fs/u-boot/include/clk.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2015 Google, Inc
3*4882a593Smuzhiyun  * Written by Simon Glass <sjg@chromium.org>
4*4882a593Smuzhiyun  * Copyright (c) 2016, NVIDIA CORPORATION.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _CLK_H_
10*4882a593Smuzhiyun #define _CLK_H_
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/errno.h>
13*4882a593Smuzhiyun #include <linux/types.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /**
16*4882a593Smuzhiyun  * A clock is a hardware signal that oscillates autonomously at a specific
17*4882a593Smuzhiyun  * frequency and duty cycle. Most hardware modules require one or more clock
18*4882a593Smuzhiyun  * signal to drive their operation. Clock signals are typically generated
19*4882a593Smuzhiyun  * externally to the HW module consuming them, by an entity this API calls a
20*4882a593Smuzhiyun  * clock provider. This API provides a standard means for drivers to enable and
21*4882a593Smuzhiyun  * disable clocks, and to set the rate at which they oscillate.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * A driver that implements UCLASS_CLOCK is a clock provider. A provider will
24*4882a593Smuzhiyun  * often implement multiple separate clocks, since the hardware it manages
25*4882a593Smuzhiyun  * often has this capability. clock_uclass.h describes the interface which
26*4882a593Smuzhiyun  * clock providers must implement.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * Clock consumers/clients are the HW modules driven by the clock signals. This
29*4882a593Smuzhiyun  * header file describes the API used by drivers for those HW modules.
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun struct udevice;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /**
35*4882a593Smuzhiyun  * struct clk - A handle to (allowing control of) a single clock.
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * Clients provide storage for clock handles. The content of the structure is
38*4882a593Smuzhiyun  * managed solely by the clock API and clock drivers. A clock struct is
39*4882a593Smuzhiyun  * initialized by "get"ing the clock struct. The clock struct is passed to all
40*4882a593Smuzhiyun  * other clock APIs to identify which clock signal to operate upon.
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  * @dev: The device which implements the clock signal.
43*4882a593Smuzhiyun  * @id: The clock signal ID within the provider.
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  * Currently, the clock API assumes that a single integer ID is enough to
46*4882a593Smuzhiyun  * identify and configure any clock signal for any clock provider. If this
47*4882a593Smuzhiyun  * assumption becomes invalid in the future, the struct could be expanded to
48*4882a593Smuzhiyun  * either (a) add more fields to allow clock providers to store additional
49*4882a593Smuzhiyun  * information, or (b) replace the id field with an opaque pointer, which the
50*4882a593Smuzhiyun  * provider would dynamically allocated during its .of_xlate op, and process
51*4882a593Smuzhiyun  * during is .request op. This may require the addition of an extra op to clean
52*4882a593Smuzhiyun  * up the allocation.
53*4882a593Smuzhiyun  */
54*4882a593Smuzhiyun struct clk {
55*4882a593Smuzhiyun 	struct udevice *dev;
56*4882a593Smuzhiyun 	/*
57*4882a593Smuzhiyun 	 * Written by of_xlate. We assume a single id is enough for now. In the
58*4882a593Smuzhiyun 	 * future, we might add more fields here.
59*4882a593Smuzhiyun 	 */
60*4882a593Smuzhiyun 	unsigned long id;
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /**
64*4882a593Smuzhiyun  * struct clk_bulk - A handle to (allowing control of) a bulk of clocks.
65*4882a593Smuzhiyun  *
66*4882a593Smuzhiyun  * Clients provide storage for the clock bulk. The content of the structure is
67*4882a593Smuzhiyun  * managed solely by the clock API. A clock bulk struct is
68*4882a593Smuzhiyun  * initialized by "get"ing the clock bulk struct.
69*4882a593Smuzhiyun  * The clock bulk struct is passed to all other bulk clock APIs to apply
70*4882a593Smuzhiyun  * the API to all the clock in the bulk struct.
71*4882a593Smuzhiyun  *
72*4882a593Smuzhiyun  * @clks: An array of clock handles.
73*4882a593Smuzhiyun  * @count: The number of clock handles in the clks array.
74*4882a593Smuzhiyun  */
75*4882a593Smuzhiyun struct clk_bulk {
76*4882a593Smuzhiyun 	struct clk *clks;
77*4882a593Smuzhiyun 	unsigned int count;
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(CLK)
81*4882a593Smuzhiyun struct phandle_1_arg;
82*4882a593Smuzhiyun int clk_get_by_index_platdata(struct udevice *dev, int index,
83*4882a593Smuzhiyun 			      struct phandle_1_arg *cells, struct clk *clk);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /**
86*4882a593Smuzhiyun  * clock_get_by_index - Get/request a clock by integer index.
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * This looks up and requests a clock. The index is relative to the client
89*4882a593Smuzhiyun  * device; each device is assumed to have n clocks associated with it somehow,
90*4882a593Smuzhiyun  * and this function finds and requests one of them. The mapping of client
91*4882a593Smuzhiyun  * device clock indices to provider clocks may be via device-tree properties,
92*4882a593Smuzhiyun  * board-provided mapping tables, or some other mechanism.
93*4882a593Smuzhiyun  *
94*4882a593Smuzhiyun  * @dev:	The client device.
95*4882a593Smuzhiyun  * @index:	The index of the clock to request, within the client's list of
96*4882a593Smuzhiyun  *		clocks.
97*4882a593Smuzhiyun  * @clock	A pointer to a clock struct to initialize.
98*4882a593Smuzhiyun  * @return 0 if OK, or a negative error code.
99*4882a593Smuzhiyun  */
100*4882a593Smuzhiyun int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun /**
103*4882a593Smuzhiyun  * clock_get_bulk - Get/request all clocks of a device.
104*4882a593Smuzhiyun  *
105*4882a593Smuzhiyun  * This looks up and requests all clocks of the client device; each device is
106*4882a593Smuzhiyun  * assumed to have n clocks associated with it somehow, and this function finds
107*4882a593Smuzhiyun  * and requests all of them in a separate structure. The mapping of client
108*4882a593Smuzhiyun  * device clock indices to provider clocks may be via device-tree properties,
109*4882a593Smuzhiyun  * board-provided mapping tables, or some other mechanism.
110*4882a593Smuzhiyun  *
111*4882a593Smuzhiyun  * @dev:	The client device.
112*4882a593Smuzhiyun  * @bulk	A pointer to a clock bulk struct to initialize.
113*4882a593Smuzhiyun  * @return 0 if OK, or a negative error code.
114*4882a593Smuzhiyun  */
115*4882a593Smuzhiyun int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun /**
118*4882a593Smuzhiyun  * clock_get_by_name - Get/request a clock by name.
119*4882a593Smuzhiyun  *
120*4882a593Smuzhiyun  * This looks up and requests a clock. The name is relative to the client
121*4882a593Smuzhiyun  * device; each device is assumed to have n clocks associated with it somehow,
122*4882a593Smuzhiyun  * and this function finds and requests one of them. The mapping of client
123*4882a593Smuzhiyun  * device clock names to provider clocks may be via device-tree properties,
124*4882a593Smuzhiyun  * board-provided mapping tables, or some other mechanism.
125*4882a593Smuzhiyun  *
126*4882a593Smuzhiyun  * @dev:	The client device.
127*4882a593Smuzhiyun  * @name:	The name of the clock to request, within the client's list of
128*4882a593Smuzhiyun  *		clocks.
129*4882a593Smuzhiyun  * @clock:	A pointer to a clock struct to initialize.
130*4882a593Smuzhiyun  * @return 0 if OK, or a negative error code.
131*4882a593Smuzhiyun  */
132*4882a593Smuzhiyun int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun /**
135*4882a593Smuzhiyun  * clk_release_all() - Disable (turn off)/Free an array of previously
136*4882a593Smuzhiyun  * requested clocks.
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  * For each clock contained in the clock array, this function will check if
139*4882a593Smuzhiyun  * clock has been previously requested and then will disable and free it.
140*4882a593Smuzhiyun  *
141*4882a593Smuzhiyun  * @clk:	A clock struct array that was previously successfully
142*4882a593Smuzhiyun  *		requested by clk_request/get_by_*().
143*4882a593Smuzhiyun  * @count	Number of clock contained in the array
144*4882a593Smuzhiyun  * @return zero on success, or -ve error code.
145*4882a593Smuzhiyun  */
146*4882a593Smuzhiyun int clk_release_all(struct clk *clk, int count);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun #else
clk_get_by_index(struct udevice * dev,int index,struct clk * clk)149*4882a593Smuzhiyun static inline int clk_get_by_index(struct udevice *dev, int index,
150*4882a593Smuzhiyun 				   struct clk *clk)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	return -ENOSYS;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun 
clk_get_bulk(struct udevice * dev,struct clk_bulk * bulk)155*4882a593Smuzhiyun static inline int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun 	return -ENOSYS;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
clk_get_by_name(struct udevice * dev,const char * name,struct clk * clk)160*4882a593Smuzhiyun static inline int clk_get_by_name(struct udevice *dev, const char *name,
161*4882a593Smuzhiyun 			   struct clk *clk)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	return -ENOSYS;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
clk_release_all(struct clk * clk,int count)166*4882a593Smuzhiyun static inline int clk_release_all(struct clk *clk, int count)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	return -ENOSYS;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun #endif
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun #if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
173*4882a593Smuzhiyun 	CONFIG_IS_ENABLED(CLK)
174*4882a593Smuzhiyun /**
175*4882a593Smuzhiyun  * clk_set_defaults - Process 'assigned-{clocks/clock-parents/clock-rates}'
176*4882a593Smuzhiyun  *                    properties to configure clocks
177*4882a593Smuzhiyun  *
178*4882a593Smuzhiyun  * @dev:        A device to process (the ofnode associated with this device
179*4882a593Smuzhiyun  *              will be processed).
180*4882a593Smuzhiyun  */
181*4882a593Smuzhiyun int clk_set_defaults(struct udevice *dev);
182*4882a593Smuzhiyun #else
clk_set_defaults(struct udevice * dev)183*4882a593Smuzhiyun static inline int clk_set_defaults(struct udevice *dev)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun 	return 0;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun #endif
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /**
190*4882a593Smuzhiyun  * clk_release_bulk() - Disable (turn off)/Free an array of previously
191*4882a593Smuzhiyun  * requested clocks in a clock bulk struct.
192*4882a593Smuzhiyun  *
193*4882a593Smuzhiyun  * For each clock contained in the clock bulk struct, this function will check
194*4882a593Smuzhiyun  * if clock has been previously requested and then will disable and free it.
195*4882a593Smuzhiyun  *
196*4882a593Smuzhiyun  * @clk:	A clock bulk struct that was previously successfully
197*4882a593Smuzhiyun  *		requested by clk_get_bulk().
198*4882a593Smuzhiyun  * @return zero on success, or -ve error code.
199*4882a593Smuzhiyun  */
clk_release_bulk(struct clk_bulk * bulk)200*4882a593Smuzhiyun static inline int clk_release_bulk(struct clk_bulk *bulk)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	return clk_release_all(bulk->clks, bulk->count);
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun /**
206*4882a593Smuzhiyun  * clk_request - Request a clock by provider-specific ID.
207*4882a593Smuzhiyun  *
208*4882a593Smuzhiyun  * This requests a clock using a provider-specific ID. Generally, this function
209*4882a593Smuzhiyun  * should not be used, since clk_get_by_index/name() provide an interface that
210*4882a593Smuzhiyun  * better separates clients from intimate knowledge of clock providers.
211*4882a593Smuzhiyun  * However, this function may be useful in core SoC-specific code.
212*4882a593Smuzhiyun  *
213*4882a593Smuzhiyun  * @dev:	The clock provider device.
214*4882a593Smuzhiyun  * @clock:	A pointer to a clock struct to initialize. The caller must
215*4882a593Smuzhiyun  *		have already initialized any field in this struct which the
216*4882a593Smuzhiyun  *		clock provider uses to identify the clock.
217*4882a593Smuzhiyun  * @return 0 if OK, or a negative error code.
218*4882a593Smuzhiyun  */
219*4882a593Smuzhiyun int clk_request(struct udevice *dev, struct clk *clk);
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /**
222*4882a593Smuzhiyun  * clock_free - Free a previously requested clock.
223*4882a593Smuzhiyun  *
224*4882a593Smuzhiyun  * @clock:	A clock struct that was previously successfully requested by
225*4882a593Smuzhiyun  *		clk_request/get_by_*().
226*4882a593Smuzhiyun  * @return 0 if OK, or a negative error code.
227*4882a593Smuzhiyun  */
228*4882a593Smuzhiyun int clk_free(struct clk *clk);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun /**
231*4882a593Smuzhiyun  * clk_get_rate() - Get current clock rate.
232*4882a593Smuzhiyun  *
233*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
234*4882a593Smuzhiyun  *		clk_request/get_by_*().
235*4882a593Smuzhiyun  * @return clock rate in Hz, or -ve error code.
236*4882a593Smuzhiyun  */
237*4882a593Smuzhiyun ulong clk_get_rate(struct clk *clk);
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun /**
240*4882a593Smuzhiyun  * clk_set_rate() - Set current clock rate.
241*4882a593Smuzhiyun  *
242*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
243*4882a593Smuzhiyun  *		clk_request/get_by_*().
244*4882a593Smuzhiyun  * @rate:	New clock rate in Hz.
245*4882a593Smuzhiyun  * @return new rate, or -ve error code.
246*4882a593Smuzhiyun  */
247*4882a593Smuzhiyun ulong clk_set_rate(struct clk *clk, ulong rate);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun /**
250*4882a593Smuzhiyun  * clk_get_phase() - Get the phase shift of a clock signal.
251*4882a593Smuzhiyun  *
252*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
253*4882a593Smuzhiyun  *		clk_request/get_by_*().
254*4882a593Smuzhiyun  * @return the phase shift of a clock node in degrees, otherwise returns
255*4882a593Smuzhiyun  *		-ve error code.
256*4882a593Smuzhiyun  */
257*4882a593Smuzhiyun int clk_get_phase(struct clk *clk);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun /**
260*4882a593Smuzhiyun  * clk_set_rate() - Adjust the phase shift of a clock signal.
261*4882a593Smuzhiyun  *
262*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
263*4882a593Smuzhiyun  *		clk_request/get_by_*().
264*4882a593Smuzhiyun  * @degrees:	Numberof degrees the signal is shifted.
265*4882a593Smuzhiyun  * @return 0 on success, or -ve error code.
266*4882a593Smuzhiyun  */
267*4882a593Smuzhiyun int clk_set_phase(struct clk *clk, int degrees);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun /**
270*4882a593Smuzhiyun  * clk_set_parent() - Set current clock parent.
271*4882a593Smuzhiyun  *
272*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
273*4882a593Smuzhiyun  *		clk_request/get_by_*().
274*4882a593Smuzhiyun  * @parent:	A clock struct that was previously successfully requested by
275*4882a593Smuzhiyun  *		clk_request/get_by_*().
276*4882a593Smuzhiyun  * @return new rate, or -ve error code.
277*4882a593Smuzhiyun  */
278*4882a593Smuzhiyun int clk_set_parent(struct clk *clk, struct clk *parent);
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun /**
281*4882a593Smuzhiyun  * clk_enable() - Enable (turn on) a clock.
282*4882a593Smuzhiyun  *
283*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
284*4882a593Smuzhiyun  *		clk_request/get_by_*().
285*4882a593Smuzhiyun  * @return zero on success, or -ve error code.
286*4882a593Smuzhiyun  */
287*4882a593Smuzhiyun int clk_enable(struct clk *clk);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun /**
290*4882a593Smuzhiyun  * clk_enable_bulk() - Enable (turn on) all clocks in a clock bulk struct.
291*4882a593Smuzhiyun  *
292*4882a593Smuzhiyun  * @bulk:	A clock bulk struct that was previously successfully requested
293*4882a593Smuzhiyun  *		by clk_get_bulk().
294*4882a593Smuzhiyun  * @return zero on success, or -ve error code.
295*4882a593Smuzhiyun  */
296*4882a593Smuzhiyun int clk_enable_bulk(struct clk_bulk *bulk);
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun /**
299*4882a593Smuzhiyun  * clk_disable() - Disable (turn off) a clock.
300*4882a593Smuzhiyun  *
301*4882a593Smuzhiyun  * @clk:	A clock struct that was previously successfully requested by
302*4882a593Smuzhiyun  *		clk_request/get_by_*().
303*4882a593Smuzhiyun  * @return zero on success, or -ve error code.
304*4882a593Smuzhiyun  */
305*4882a593Smuzhiyun int clk_disable(struct clk *clk);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun /**
308*4882a593Smuzhiyun  * clk_disable_bulk() - Disable (turn off) all clocks in a clock bulk struct.
309*4882a593Smuzhiyun  *
310*4882a593Smuzhiyun  * @bulk:	A clock bulk struct that was previously successfully requested
311*4882a593Smuzhiyun  *		by clk_get_bulk().
312*4882a593Smuzhiyun  * @return zero on success, or -ve error code.
313*4882a593Smuzhiyun  */
314*4882a593Smuzhiyun int clk_disable_bulk(struct clk_bulk *bulk);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun int soc_clk_dump(void);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun int clks_probe(void);
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun /**
321*4882a593Smuzhiyun  * clk_valid() - check if clk is valid
322*4882a593Smuzhiyun  *
323*4882a593Smuzhiyun  * @clk:	the clock to check
324*4882a593Smuzhiyun  * @return true if valid, or false
325*4882a593Smuzhiyun  */
clk_valid(struct clk * clk)326*4882a593Smuzhiyun static inline bool clk_valid(struct clk *clk)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	return !!clk->dev;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun #endif
331