blob: f62e7536cd543d4a5fd749b75ba22b45547d6f61 [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
77#define F_RAW(f, sc, m_v, n_v, c_v, m_m, v, e) { \
78 .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, \
84 .sys_vdd = v, \
85 .extra_freq_data = e, \
86 }
87#define FREQ_END (UINT_MAX-1)
88#define F_END \
89 { \
90 .freq_hz = FREQ_END, \
91 .sys_vdd = LOW, \
92 }
93
94/**
95 * struct branch - branch on/off
96 * @ctl_reg: clock control register
97 * @en_mask: ORed with @ctl_reg to enable the clock
98 * @halt_reg: halt register
99 * @halt_check: type of halt check to perform
100 * @halt_bit: ANDed with @halt_reg to test for clock halted
101 * @reset_reg: reset register
102 * @reset_mask: ORed with @reset_reg to reset the clock domain
103 */
104struct branch {
105 void __iomem *const ctl_reg;
106 const u32 en_mask;
107
108 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
116int branch_reset(struct branch *clk, enum clk_reset_action action);
117
118/*
119 * Generic clock-definition struct and macros
120 */
121struct rcg_clk {
122 bool enabled;
123 void *const ns_reg;
124 void *const md_reg;
125
126 const uint32_t root_en_mask;
127 uint32_t ns_mask;
128 const uint32_t ctl_mask;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700129
Stephen Boydc78d9a72011-07-20 00:46:24 -0700130 void *bank_info;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700131 void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
Stephen Boydc78d9a72011-07-20 00:46:24 -0700132
Tianyi Goubaf6d342011-08-30 21:49:02 -0700133 struct clk_freq_tbl *freq_tbl;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134 struct clk_freq_tbl *current_freq;
135
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700136 struct branch b;
137 struct clk c;
138};
139
140static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
141{
142 return container_of(clk, struct rcg_clk, c);
143}
144
Matt Wagantall84f43fd2011-08-16 23:28:38 -0700145extern struct clk_freq_tbl rcg_dummy_freq;
146
Matt Wagantall0625ea02011-07-13 18:51:56 -0700147int rcg_clk_enable(struct clk *clk);
148void rcg_clk_disable(struct clk *clk);
149void rcg_clk_auto_off(struct clk *clk);
150int rcg_clk_set_rate(struct clk *clk, unsigned rate);
151int rcg_clk_set_min_rate(struct clk *clk, unsigned rate);
Matt Wagantall0625ea02011-07-13 18:51:56 -0700152unsigned rcg_clk_get_rate(struct clk *clk);
153int rcg_clk_list_rate(struct clk *clk, unsigned n);
154int rcg_clk_is_enabled(struct clk *clk);
155long rcg_clk_round_rate(struct clk *clk, unsigned rate);
156struct clk *rcg_clk_get_parent(struct clk *c);
Matt Wagantall271a6cd2011-09-20 16:06:31 -0700157int rcg_clk_handoff(struct clk *c);
Matt Wagantall0625ea02011-07-13 18:51:56 -0700158
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700159/*
160 * SYS_VDD voltage levels
161 */
162enum sys_vdd_level {
163 NONE,
164 LOW,
165 NOMINAL,
166 HIGH,
167 NUM_SYS_VDD_LEVELS
168};
169
170/**
171 * struct fixed_clk - fixed rate clock (used for crystal oscillators)
172 * @rate: output rate
173 * @c: clk
174 */
175struct fixed_clk {
176 unsigned long rate;
177 struct clk c;
178};
179
180static inline struct fixed_clk *to_fixed_clk(struct clk *clk)
181{
182 return container_of(clk, struct fixed_clk, c);
183}
184
185static inline unsigned fixed_clk_get_rate(struct clk *clk)
186{
187 struct fixed_clk *f = to_fixed_clk(clk);
188 return f->rate;
189}
190
191
192/**
193 * struct pll_vote_clk - phase locked loop (HW voteable)
194 * @rate: output rate
195 * @en_reg: enable register
196 * @en_mask: ORed with @en_reg to enable the clock
197 * @status_reg: status register
198 * @parent: clock source
199 * @c: clk
200 */
201struct pll_vote_clk {
202 unsigned long rate;
203
204 void __iomem *const en_reg;
205 const u32 en_mask;
206
207 void __iomem *const status_reg;
208
209 struct clk *parent;
210 struct clk c;
211};
212
213extern struct clk_ops clk_ops_pll_vote;
214
215static inline struct pll_vote_clk *to_pll_vote_clk(struct clk *clk)
216{
217 return container_of(clk, struct pll_vote_clk, c);
218}
219
220/**
221 * struct pll_clk - phase locked loop
222 * @rate: output rate
223 * @mode_reg: enable register
224 * @parent: clock source
225 * @c: clk
226 */
227struct pll_clk {
228 unsigned long rate;
229
230 void __iomem *const mode_reg;
231
232 struct clk *parent;
233 struct clk c;
234};
235
236extern struct clk_ops clk_ops_pll;
237
238static inline struct pll_clk *to_pll_clk(struct clk *clk)
239{
240 return container_of(clk, struct pll_clk, c);
241}
242
Vikram Mulukutla489e39e2011-08-31 18:04:05 -0700243int sr_pll_clk_enable(struct clk *clk);
244
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700245/**
246 * struct branch_clk - branch
247 * @enabled: true if clock is on, false otherwise
248 * @b: branch
249 * @parent: clock source
250 * @c: clk
251 *
252 * An on/off switch with a rate derived from the parent.
253 */
254struct branch_clk {
255 bool enabled;
256 struct branch b;
257 struct clk *parent;
258 struct clk c;
259};
260
261static inline struct branch_clk *to_branch_clk(struct clk *clk)
262{
263 return container_of(clk, struct branch_clk, c);
264}
265
266int branch_clk_enable(struct clk *clk);
267void branch_clk_disable(struct clk *clk);
268struct clk *branch_clk_get_parent(struct clk *clk);
269int branch_clk_set_parent(struct clk *clk, struct clk *parent);
270int branch_clk_is_enabled(struct clk *clk);
271void branch_clk_auto_off(struct clk *clk);
272int branch_clk_reset(struct clk *c, enum clk_reset_action action);
273
274/**
275 * struct measure_clk - for rate measurement debug use
276 * @sample_ticks: sample period in reference clock ticks
277 * @multiplier: measurement scale-up factor
278 * @divider: measurement scale-down factor
279 * @c: clk
280*/
281struct measure_clk {
282 u64 sample_ticks;
283 u32 multiplier;
284 u32 divider;
285 struct clk c;
286};
287
288extern struct clk_ops clk_ops_measure;
289
290static inline struct measure_clk *to_measure_clk(struct clk *clk)
291{
292 return container_of(clk, struct measure_clk, c);
293}
294
295/*
296 * Variables from clock-local driver
297 */
298extern spinlock_t local_clock_reg_lock;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700299extern struct fixed_clk gnd_clk;
300
301/*
302 * Local-clock APIs
303 */
304int local_vote_sys_vdd(enum sys_vdd_level level);
305int local_unvote_sys_vdd(enum sys_vdd_level level);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700306bool local_clk_is_local(struct clk *clk);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700307
308/*
309 * Required SoC-specific functions, implemented for every supported SoC
310 */
311extern int (*soc_update_sys_vdd)(enum sys_vdd_level level);
312
313/*
314 * Generic set-rate implementations
315 */
316void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
317void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf);
318void set_rate_mnd_8(struct rcg_clk *clk, struct clk_freq_tbl *nf);
319void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
320void set_rate_div_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
321
322#endif /* __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_H */
323