blob: a561802de5758ea49b7eaad19e347124bc57b9d9 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#ifndef __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_H
15#define __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_H
16
17#include <linux/spinlock.h>
18#include "clock.h"
19
20/*
21 * Bit manipulation macros
22 */
23#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)
24#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
25
26/*
27 * Halt/Status Checking Mode Macros
28 */
29#define HALT 0 /* Bit pol: 1 = halted */
30#define NOCHECK 1 /* No bit to check, do nothing */
31#define HALT_VOTED 2 /* Bit pol: 1 = halted; delay on disable */
32#define ENABLE 3 /* Bit pol: 1 = running */
33#define ENABLE_VOTED 4 /* Bit pol: 1 = running; delay on disable */
34#define DELAY 5 /* No bit to check, just delay */
35
36/*
37 * Clock Definition Macros
38 */
39#define DEFINE_CLK_MEASURE(name) \
40 struct clk name = { \
41 .ops = &clk_ops_measure, \
42 .dbg_name = #name, \
43 CLK_INIT(name), \
44 }; \
45
46/*
47 * Generic frequency-definition structs and macros
48 */
49struct clk_freq_tbl {
50 const uint32_t freq_hz;
51 struct clk *src_clk;
52 const uint32_t md_val;
53 const uint32_t ns_val;
54 const uint32_t ctl_val;
55 uint32_t mnd_en_mask;
56 const unsigned sys_vdd;
57 void *const extra_freq_data;
58};
59
60/* Some clocks have two banks to avoid glitches when switching frequencies.
61 * The unused bank is programmed while running on the other bank, and
62 * switched to afterwards. The following two structs describe the banks. */
63struct bank_mask_info {
64 void *const md_reg;
65 const uint32_t ns_mask;
66 const uint32_t rst_mask;
67 const uint32_t mnd_en_mask;
68 const uint32_t mode_mask;
69};
70
71struct bank_masks {
72 const uint32_t bank_sel_mask;
73 const struct bank_mask_info bank0_mask;
74 const struct bank_mask_info bank1_mask;
75};
76
Matt Wagantalle18bbc82011-10-06 10:07:28 -070077#define F_RAW(f, sc, m_v, n_v, c_v, m_m, e) { \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070078 .freq_hz = f, \
79 .src_clk = sc, \
80 .md_val = m_v, \
81 .ns_val = n_v, \
82 .ctl_val = c_v, \
83 .mnd_en_mask = m_m, \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070084 .extra_freq_data = e, \
85 }
86#define FREQ_END (UINT_MAX-1)
Matt Wagantalle18bbc82011-10-06 10:07:28 -070087#define F_END { .freq_hz = FREQ_END }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070088
89/**
90 * struct branch - branch on/off
91 * @ctl_reg: clock control register
92 * @en_mask: ORed with @ctl_reg to enable the clock
Stephen Boyda52d7e32011-11-10 11:59:00 -080093 * @hwcg_reg: hardware clock gating register
94 * @hwcg_mask: ORed with @hwcg_reg to enable hardware clock gating
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095 * @halt_reg: halt register
96 * @halt_check: type of halt check to perform
97 * @halt_bit: ANDed with @halt_reg to test for clock halted
98 * @reset_reg: reset register
99 * @reset_mask: ORed with @reset_reg to reset the clock domain
100 */
101struct branch {
102 void __iomem *const ctl_reg;
103 const u32 en_mask;
104
Stephen Boyda52d7e32011-11-10 11:59:00 -0800105 void __iomem *hwcg_reg;
106 u32 hwcg_mask;
107
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700108 void __iomem *const halt_reg;
109 const u16 halt_check;
110 const u16 halt_bit;
111
112 void __iomem *const reset_reg;
113 const u32 reset_mask;
114};
115
Stephen Boyda52d7e32011-11-10 11:59:00 -0800116int branch_reset(struct branch *b, enum clk_reset_action action);
Stephen Boyd092fd182011-10-21 15:56:30 -0700117void __branch_clk_enable_reg(const struct branch *clk, const char *name);
118u32 __branch_clk_disable_reg(const struct branch *clk, const char *name);
Stephen Boyda52d7e32011-11-10 11:59:00 -0800119int branch_clk_handoff(struct clk *c);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120
121/*
122 * Generic clock-definition struct and macros
123 */
124struct rcg_clk {
125 bool enabled;
126 void *const ns_reg;
127 void *const md_reg;
128
129 const uint32_t root_en_mask;
130 uint32_t ns_mask;
131 const uint32_t ctl_mask;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700132
Stephen Boydc78d9a72011-07-20 00:46:24 -0700133 void *bank_info;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134 void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
Stephen Boydc78d9a72011-07-20 00:46:24 -0700135
Tianyi Goubaf6d342011-08-30 21:49:02 -0700136 struct clk_freq_tbl *freq_tbl;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 struct clk_freq_tbl *current_freq;
138
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700139 struct branch b;
140 struct clk c;
141};
142
143static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
144{
145 return container_of(clk, struct rcg_clk, c);
146}
147
Matt Wagantall84f43fd2011-08-16 23:28:38 -0700148extern struct clk_freq_tbl rcg_dummy_freq;
149
Matt Wagantall0625ea02011-07-13 18:51:56 -0700150int rcg_clk_enable(struct clk *clk);
151void rcg_clk_disable(struct clk *clk);
Matt Wagantall9de3bfb2011-11-03 20:13:12 -0700152int rcg_clk_set_rate(struct clk *clk, unsigned long rate);
Matt Wagantall9de3bfb2011-11-03 20:13:12 -0700153unsigned long rcg_clk_get_rate(struct clk *clk);
Matt Wagantall0625ea02011-07-13 18:51:56 -0700154int rcg_clk_list_rate(struct clk *clk, unsigned n);
155int rcg_clk_is_enabled(struct clk *clk);
Matt Wagantall9de3bfb2011-11-03 20:13:12 -0700156long rcg_clk_round_rate(struct clk *clk, unsigned long rate);
Matt Wagantall0625ea02011-07-13 18:51:56 -0700157struct clk *rcg_clk_get_parent(struct clk *c);
Matt Wagantall271a6cd2011-09-20 16:06:31 -0700158int rcg_clk_handoff(struct clk *c);
Stephen Boyd7bf28142011-12-07 00:30:52 -0800159int rcg_clk_reset(struct clk *clk, enum clk_reset_action action);
Stephen Boyda52d7e32011-11-10 11:59:00 -0800160void rcg_clk_enable_hwcg(struct clk *clk);
161void rcg_clk_disable_hwcg(struct clk *clk);
162int rcg_clk_in_hwcg_mode(struct clk *c);
Matt Wagantall0625ea02011-07-13 18:51:56 -0700163
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700164/**
Stephen Boydb8ad8222011-11-28 12:17:58 -0800165 * struct cdiv_clk - integer divider clock with external source selection
166 * @ns_reg: source select and divider settings register
167 * @ext_mask: bit to set to select an external source
168 * @cur_div: current divider setting (or 0 for external source)
169 * @max_div: maximum divider value supported (must be power of 2)
170 * @div_offset: number of bits to shift divider left by in @ns_reg
171 * @b: branch
172 * @c: clock
173 */
174struct cdiv_clk {
175 void __iomem *const ns_reg;
176 u32 ext_mask;
177
178 unsigned long cur_div;
179 u8 div_offset;
180 u32 max_div;
181
182 struct branch b;
183 struct clk c;
184};
185
186static inline struct cdiv_clk *to_cdiv_clk(struct clk *clk)
187{
188 return container_of(clk, struct cdiv_clk, c);
189}
190
191extern struct clk_ops clk_ops_cdiv;
192
193/**
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700194 * struct fixed_clk - fixed rate clock (used for crystal oscillators)
195 * @rate: output rate
196 * @c: clk
197 */
198struct fixed_clk {
199 unsigned long rate;
200 struct clk c;
201};
202
203static inline struct fixed_clk *to_fixed_clk(struct clk *clk)
204{
205 return container_of(clk, struct fixed_clk, c);
206}
207
Matt Wagantall9de3bfb2011-11-03 20:13:12 -0700208static inline unsigned long fixed_clk_get_rate(struct clk *clk)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700209{
210 struct fixed_clk *f = to_fixed_clk(clk);
211 return f->rate;
212}
213
214
215/**
216 * struct pll_vote_clk - phase locked loop (HW voteable)
217 * @rate: output rate
Vikram Mulukutla31680ae2011-11-04 14:23:55 -0700218 * @soft_vote: soft voting variable for multiple PLL software instances
219 * @soft_vote_mask: soft voting mask for multiple PLL software instances
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700220 * @en_reg: enable register
221 * @en_mask: ORed with @en_reg to enable the clock
222 * @status_reg: status register
223 * @parent: clock source
224 * @c: clk
225 */
226struct pll_vote_clk {
227 unsigned long rate;
228
Vikram Mulukutla31680ae2011-11-04 14:23:55 -0700229 u32 *soft_vote;
230 const u32 soft_vote_mask;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700231 void __iomem *const en_reg;
232 const u32 en_mask;
233
234 void __iomem *const status_reg;
235
236 struct clk *parent;
237 struct clk c;
238};
239
240extern struct clk_ops clk_ops_pll_vote;
241
242static inline struct pll_vote_clk *to_pll_vote_clk(struct clk *clk)
243{
244 return container_of(clk, struct pll_vote_clk, c);
245}
246
247/**
248 * struct pll_clk - phase locked loop
249 * @rate: output rate
250 * @mode_reg: enable register
251 * @parent: clock source
252 * @c: clk
253 */
254struct pll_clk {
255 unsigned long rate;
256
257 void __iomem *const mode_reg;
258
259 struct clk *parent;
260 struct clk c;
261};
262
263extern struct clk_ops clk_ops_pll;
264
265static inline struct pll_clk *to_pll_clk(struct clk *clk)
266{
267 return container_of(clk, struct pll_clk, c);
268}
269
Vikram Mulukutla489e39e2011-08-31 18:04:05 -0700270int sr_pll_clk_enable(struct clk *clk);
271
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700272/**
273 * struct branch_clk - branch
274 * @enabled: true if clock is on, false otherwise
275 * @b: branch
276 * @parent: clock source
277 * @c: clk
278 *
279 * An on/off switch with a rate derived from the parent.
280 */
281struct branch_clk {
282 bool enabled;
283 struct branch b;
284 struct clk *parent;
285 struct clk c;
286};
287
288static inline struct branch_clk *to_branch_clk(struct clk *clk)
289{
290 return container_of(clk, struct branch_clk, c);
291}
292
293int branch_clk_enable(struct clk *clk);
294void branch_clk_disable(struct clk *clk);
295struct clk *branch_clk_get_parent(struct clk *clk);
296int branch_clk_set_parent(struct clk *clk, struct clk *parent);
297int branch_clk_is_enabled(struct clk *clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700298int branch_clk_reset(struct clk *c, enum clk_reset_action action);
Stephen Boyda52d7e32011-11-10 11:59:00 -0800299void branch_clk_enable_hwcg(struct clk *clk);
300void branch_clk_disable_hwcg(struct clk *clk);
301int branch_clk_in_hwcg_mode(struct clk *c);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700302
303/**
304 * struct measure_clk - for rate measurement debug use
305 * @sample_ticks: sample period in reference clock ticks
306 * @multiplier: measurement scale-up factor
307 * @divider: measurement scale-down factor
308 * @c: clk
309*/
310struct measure_clk {
311 u64 sample_ticks;
312 u32 multiplier;
313 u32 divider;
314 struct clk c;
315};
316
317extern struct clk_ops clk_ops_measure;
318
319static inline struct measure_clk *to_measure_clk(struct clk *clk)
320{
321 return container_of(clk, struct measure_clk, c);
322}
323
324/*
325 * Variables from clock-local driver
326 */
327extern spinlock_t local_clock_reg_lock;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328extern struct fixed_clk gnd_clk;
329
330/*
331 * Local-clock APIs
332 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700333bool local_clk_is_local(struct clk *clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700334
335/*
Vikram Mulukutla31680ae2011-11-04 14:23:55 -0700336 * PLL vote clock APIs
337 */
338int pll_vote_clk_enable(struct clk *clk);
339void pll_vote_clk_disable(struct clk *clk);
340unsigned long pll_vote_clk_get_rate(struct clk *clk);
341struct clk *pll_vote_clk_get_parent(struct clk *clk);
342int pll_vote_clk_is_enabled(struct clk *clk);
343
344/*
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700345 * Generic set-rate implementations
346 */
347void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
348void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf);
349void set_rate_mnd_8(struct rcg_clk *clk, struct clk_freq_tbl *nf);
350void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
351void set_rate_div_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
352
353#endif /* __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_H */
354