summaryrefslogtreecommitdiffstats
path: root/include/linux/clk-provider.h
blob: 5508897ad376054102e263958693573260ebe23b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/*
 *  linux/include/linux/clk-provider.h
 *
 *  Copyright (c) 2010-2011 Jeremy Kerr <jeremy.kerr@canonical.com>
 *  Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#ifndef __LINUX_CLK_PROVIDER_H
#define __LINUX_CLK_PROVIDER_H

#include <linux/clk.h>

#ifdef CONFIG_COMMON_CLK

/**
 * struct clk_hw - handle for traversing from a struct clk to its corresponding
 * hardware-specific structure.  struct clk_hw should be declared within struct
 * clk_foo and then referenced by the struct clk instance that uses struct
 * clk_foo's clk_ops
 *
 * clk: pointer to the struct clk instance that points back to this struct
 * clk_hw instance
 */
struct clk_hw {
	struct clk *clk;
};

/*
 * flags used across common struct clk.  these flags should only affect the
 * top-level framework.  custom flags for dealing with hardware specifics
 * belong in struct clk_foo
 */
#define CLK_SET_RATE_GATE	BIT(0) /* must be gated across rate change */
#define CLK_SET_PARENT_GATE	BIT(1) /* must be gated across re-parent */
#define CLK_SET_RATE_PARENT	BIT(2) /* propagate rate change up one level */
#define CLK_IGNORE_UNUSED	BIT(3) /* do not gate even if unused */
#define CLK_IS_ROOT		BIT(4) /* root clk, has no parent */

/**
 * struct clk_ops -  Callback operations for hardware clocks; these are to
 * be provided by the clock implementation, and will be called by drivers
 * through the clk_* api.
 *
 * @prepare:	Prepare the clock for enabling. This must not return until
 * 		the clock is fully prepared, and it's safe to call clk_enable.
 * 		This callback is intended to allow clock implementations to
 * 		do any initialisation that may sleep. Called with
 * 		prepare_lock held.
 *
 * @unprepare:	Release the clock from its prepared state. This will typically
 * 		undo any work done in the @prepare callback. Called with
 * 		prepare_lock held.
 *
 * @enable:	Enable the clock atomically. This must not return until the
 * 		clock is generating a valid clock signal, usable by consumer
 * 		devices. Called with enable_lock held. This function must not
 * 		sleep.
 *
 * @disable:	Disable the clock atomically. Called with enable_lock held.
 * 		This function must not sleep.
 *
 * @recalc_rate	Recalculate the rate of this clock, by quering hardware.  The
 * 		parent rate is an input parameter.  It is up to the caller to
 * 		insure that the prepare_mutex is held across this call.
 * 		Returns the calculated rate.  Optional, but recommended - if
 * 		this op is not set then clock rate will be initialized to 0.
 *
 * @round_rate:	Given a target rate as input, returns the closest rate actually
 * 		supported by the clock.
 *
 * @get_parent:	Queries the hardware to determine the parent of a clock.  The
 * 		return value is a u8 which specifies the index corresponding to
 * 		the parent clock.  This index can be applied to either the
 * 		.parent_names or .parents arrays.  In short, this function
 * 		translates the parent value read from hardware into an array
 * 		index.  Currently only called when the clock is initialized by
 * 		__clk_init.  This callback is mandatory for clocks with
 * 		multiple parents.  It is optional (and unnecessary) for clocks
 * 		with 0 or 1 parents.
 *
 * @set_parent:	Change the input source of this clock; for clocks with multiple
 * 		possible parents specify a new parent by passing in the index
 * 		as a u8 corresponding to the parent in either the .parent_names
 * 		or .parents arrays.  This function in affect translates an
 * 		array index into the value programmed into the hardware.
 * 		Returns 0 on success, -EERROR otherwise.
 *
 * @set_rate:	Change the rate of this clock. If this callback returns
 * 		CLK_SET_RATE_PARENT, the rate change will be propagated to the
 * 		parent clock (which may propagate again if the parent clock
 * 		also sets this flag). The requested rate of the parent is
 * 		passed back from the callback in the second 'unsigned long *'
 * 		argument.  Note that it is up to the hardware clock's set_rate
 * 		implementation to insure that clocks do not run out of spec
 * 		when propgating the call to set_rate up to the parent.  One way
 * 		to do this is to gate the clock (via clk_disable and/or
 * 		clk_unprepare) before calling clk_set_rate, then ungating it
 * 		afterward.  If your clock also has the CLK_GATE_SET_RATE flag
 * 		set then this will insure safety.  Returns 0 on success,
 * 		-EERROR otherwise.
 *
 * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
 * implementations to split any work between atomic (enable) and sleepable
 * (prepare) contexts.  If enabling a clock requires code that might sleep,
 * this must be done in clk_prepare.  Clock enable code that will never be
 * called in a sleepable context may be implement in clk_enable.
 *
 * Typically, drivers will call clk_prepare when a clock may be needed later
 * (eg. when a device is opened), and clk_enable when the clock is actually
 * required (eg. from an interrupt). Note that clk_prepare MUST have been
 * called before clk_enable.
 */
struct clk_ops {
	int		(*prepare)(struct clk_hw *hw);
	void		(*unprepare)(struct clk_hw *hw);
	int		(*enable)(struct clk_hw *hw);
	void		(*disable)(struct clk_hw *hw);
	int		(*is_enabled)(struct clk_hw *hw);
	unsigned long	(*recalc_rate)(struct clk_hw *hw,
					unsigned long parent_rate);
	long		(*round_rate)(struct clk_hw *hw, unsigned long,
					unsigned long *);
	int		(*set_parent)(struct clk_hw *hw, u8 index);
	u8		(*get_parent)(struct clk_hw *hw);
	int		(*set_rate)(struct clk_hw *hw, unsigned long);
	void		(*init)(struct clk_hw *hw);
};

/*
 * DOC: Basic clock implementations common to many platforms
 *
 * Each basic clock hardware type is comprised of a structure describing the
 * clock hardware, implementations of the relevant callbacks in struct clk_ops,
 * unique flags for that hardware type, a registration function and an
 * alternative macro for static initialization
 */

/**
 * struct clk_fixed_rate - fixed-rate clock
 * @hw:		handle between common and hardware-specific interfaces
 * @fixed_rate:	constant frequency of clock
 */
struct clk_fixed_rate {
	struct		clk_hw hw;
	unsigned long	fixed_rate;
	u8		flags;
};

struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		unsigned long fixed_rate);

/**
 * struct clk_gate - gating clock
 *
 * @hw:		handle between common and hardware-specific interfaces
 * @reg:	register controlling gate
 * @bit_idx:	single bit controlling gate
 * @flags:	hardware-specific flags
 * @lock:	register lock
 *
 * Clock which can gate its output.  Implements .enable & .disable
 *
 * Flags:
 * CLK_GATE_SET_DISABLE - by default this clock sets the bit at bit_idx to
 * 	enable the clock.  Setting this flag does the opposite: setting the bit
 * 	disable the clock and clearing it enables the clock
 */
struct clk_gate {
	struct clk_hw hw;
	void __iomem	*reg;
	u8		bit_idx;
	u8		flags;
	spinlock_t	*lock;
	char		*parent[1];
};

#define CLK_GATE_SET_TO_DISABLE		BIT(0)

struct clk *clk_register_gate(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 bit_idx,
		u8 clk_gate_flags, spinlock_t *lock);

/**
 * struct clk_divider - adjustable divider clock
 *
 * @hw:		handle between common and hardware-specific interfaces
 * @reg:	register containing the divider
 * @shift:	shift to the divider bit field
 * @width:	width of the divider bit field
 * @lock:	register lock
 *
 * Clock with an adjustable divider affecting its output frequency.  Implements
 * .recalc_rate, .set_rate and .round_rate
 *
 * Flags:
 * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the
 * 	register plus one.  If CLK_DIVIDER_ONE_BASED is set then the divider is
 * 	the raw value read from the register, with the value of zero considered
 * 	invalid
 * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from
 * 	the hardware register
 */
struct clk_divider {
	struct clk_hw	hw;
	void __iomem	*reg;
	u8		shift;
	u8		width;
	u8		flags;
	spinlock_t	*lock;
	char		*parent[1];
};

#define CLK_DIVIDER_ONE_BASED		BIT(0)
#define CLK_DIVIDER_POWER_OF_TWO	BIT(1)

struct clk *clk_register_divider(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags,
		void __iomem *reg, u8 shift, u8 width,
		u8 clk_divider_flags, spinlock_t *lock);

/**
 * struct clk_mux - multiplexer clock
 *
 * @hw:		handle between common and hardware-specific interfaces
 * @reg:	register controlling multiplexer
 * @shift:	shift to multiplexer bit field
 * @width:	width of mutliplexer bit field
 * @num_clks:	number of parent clocks
 * @lock:	register lock
 *
 * Clock with multiple selectable parents.  Implements .get_parent, .set_parent
 * and .recalc_rate
 *
 * Flags:
 * CLK_MUX_INDEX_ONE - register index starts at 1, not 0
 * CLK_MUX_INDEX_BITWISE - register index is a single bit (power of two)
 */
struct clk_mux {
	struct clk_hw	hw;
	void __iomem	*reg;
	u8		shift;
	u8		width;
	u8		flags;
	spinlock_t	*lock;
};

#define CLK_MUX_INDEX_ONE		BIT(0)
#define CLK_MUX_INDEX_BIT		BIT(1)

struct clk *clk_register_mux(struct device *dev, const char *name,
		char **parent_names, u8 num_parents, unsigned long flags,
		void __iomem *reg, u8 shift, u8 width,
		u8 clk_mux_flags, spinlock_t *lock);

/**
 * clk_register - allocate a new clock, register it and return an opaque cookie
 * @dev: device that is registering this clock
 * @name: clock name
 * @ops: operations this clock supports
 * @hw: link to hardware-specific clock data
 * @parent_names: array of string names for all possible parents
 * @num_parents: number of possible parents
 * @flags: framework-level hints and quirks
 *
 * clk_register is the primary interface for populating the clock tree with new
 * clock nodes.  It returns a pointer to the newly allocated struct clk which
 * cannot be dereferenced by driver code but may be used in conjuction with the
 * rest of the clock API.
 */
struct clk *clk_register(struct device *dev, const char *name,
		const struct clk_ops *ops, struct clk_hw *hw,
		char **parent_names, u8 num_parents, unsigned long flags);

/* helper functions */
const char *__clk_get_name(struct clk *clk);
struct clk_hw *__clk_get_hw(struct clk *clk);
u8 __clk_get_num_parents(struct clk *clk);
struct clk *__clk_get_parent(struct clk *clk);
inline int __clk_get_enable_count(struct clk *clk);
inline int __clk_get_prepare_count(struct clk *clk);
unsigned long __clk_get_rate(struct clk *clk);
unsigned long __clk_get_flags(struct clk *clk);
int __clk_is_enabled(struct clk *clk);
struct clk *__clk_lookup(const char *name);

/*
 * FIXME clock api without lock protection
 */
int __clk_prepare(struct clk *clk);
void __clk_unprepare(struct clk *clk);
void __clk_reparent(struct clk *clk, struct clk *new_parent);
unsigned long __clk_round_rate(struct clk *clk, unsigned long rate);

#endif /* CONFIG_COMMON_CLK */
#endif /* CLK_PROVIDER_H */
OpenPOWER on IntegriCloud