blob: 7a7d9fd2f996ce5e388b820bd71eab96236d1f57 [file] [log] [blame]
Shashank Mittal30262902012-02-21 15:37:24 -08001/*
Channagoud Kadabi9dd522f2013-10-10 12:30:10 -07002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Shashank Mittal30262902012-02-21 15:37:24 -08003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
Duy Truongf3ac7b32013-02-13 01:07:28 -080011 * * Neither the name of The Linux Foundation nor
Shashank Mittal30262902012-02-21 15:37:24 -080012 * the names of its contributors may be used to endorse or promote
13 * products derived from this software without specific prior written
14 * permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef CLOCK_LOCAL_H
30#define CLOCK_LOCAL_H
31
32struct clk;
33struct clk_ops;
34
35#define FREQ_END (UINT_MAX-1)
36#define F_END \
37 { \
38 .freq_hz = FREQ_END, \
39 }
40
41#define container_of(ptr, type, member) \
42 ((type *)((addr_t)(ptr) - offsetof(type, member)))
43
44/*
45 * Bit manipulation macros
46 */
47#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)
48#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb))
49
50/*
51 * Halt/Status Checking Mode Macros
52 */
53#define HALT 0 /* Bit pol: 1 = halted */
54#define NOCHECK 1 /* No bit to check, do nothing */
55#define HALT_VOTED 2 /* Bit pol: 1 = halted; delay on disable */
56#define ENABLE 3 /* Bit pol: 1 = running */
57#define ENABLE_VOTED 4 /* Bit pol: 1 = running; delay on disable */
58#define DELAY 5 /* No bit to check, just delay */
59
60/*
61 * Variables from clock-local driver
62 */
63extern struct fixed_clk gnd_clk;
64
65/*
66 * Generic frequency-definition structs and macros
67 */
68struct clk_freq_tbl {
69 const uint32_t freq_hz;
70 struct clk *src_clk;
71 const uint32_t md_val;
72 const uint32_t ns_val;
73 const uint32_t ctl_val;
74 uint32_t mnd_en_mask;
75 void *const extra_freq_data;
76};
77
78extern struct clk_freq_tbl local_dummy_freq;
79
80/* Some clocks have two banks to avoid glitches when switching frequencies.
81 * The unused bank is programmed while running on the other bank, and
82 * switched to afterwards. The following two structs describe the banks. */
83struct bank_mask_info {
84 void *const md_reg;
85 const uint32_t ns_mask;
86 const uint32_t rst_mask;
87 const uint32_t mnd_en_mask;
88 const uint32_t mode_mask;
89};
90
91struct bank_masks {
92 const uint32_t bank_sel_mask;
93 const struct bank_mask_info bank0_mask;
94 const struct bank_mask_info bank1_mask;
95};
96
97/**
98 * struct branch - branch on/off
99 * @ctl_reg: clock control register
100 * @en_mask: ORed with @ctl_reg to enable the clock
101 * @halt_reg: halt register
102 * @halt_check: type of halt check to perform
103 * @halt_bit: ANDed with @halt_reg to test for clock halted
104 * @reset_reg: reset register
105 * @reset_mask: ORed with @reset_reg to reset the clock domain
106 */
107struct branch {
108 void *const ctl_reg;
109 const uint32_t en_mask;
110
111 void *const halt_reg;
112 const uint16_t halt_check;
113 const uint16_t halt_bit;
114
115 void *const reset_reg;
116 const uint32_t reset_mask;
117};
118
119/*
120 * Generic clock-definition struct and macros
121 */
122struct rcg_clk {
123 bool enabled;
124 void *const ns_reg;
125 void *const md_reg;
126
127 const uint32_t root_en_mask;
128 uint32_t ns_mask;
129 const uint32_t ctl_mask;
130 struct bank_masks *const bank_masks;
131
132 void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
Channagoud Kadabi9dd522f2013-10-10 12:30:10 -0700133 struct clk_freq_tbl *freq_tbl;
Shashank Mittal30262902012-02-21 15:37:24 -0800134 struct clk_freq_tbl *current_freq;
135
136 struct clk *depends;
137 struct branch b;
138 struct clk c;
139};
140
141static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
142{
143 return container_of(clk, struct rcg_clk, c);
144}
145
146/**
147 * struct fixed_clk - fixed rate clock (used for crystal oscillators)
148 * @rate: output rate
149 * @c: clk
150 */
151struct fixed_clk {
152 unsigned long rate;
153 struct clk c;
154};
155
156static inline struct fixed_clk *to_fixed_clk(struct clk *clk)
157{
158 return container_of(clk, struct fixed_clk, c);
159}
160
161static inline unsigned fixed_clk_get_rate(struct clk *clk)
162{
163 struct fixed_clk *f = to_fixed_clk(clk);
164 return f->rate;
165}
166
167/**
Shashank Mittal30262902012-02-21 15:37:24 -0800168 * struct branch_clk - branch
169 * @enabled: true if clock is on, false otherwise
170 * @b: branch
171 * @parent: clock source
172 * @c: clk
173 *
174 * An on/off switch with a rate derived from the parent.
175 */
176struct branch_clk {
177 bool enabled;
178 struct branch b;
179 struct clk *parent;
180 struct clk c;
181};
182
183static inline struct branch_clk *to_branch_clk(struct clk *clk)
184{
185 return container_of(clk, struct branch_clk, c);
186}
187
188int branch_clk_enable(struct clk *clk);
189void branch_clk_disable(struct clk *clk);
190struct clk *branch_clk_get_parent(struct clk *clk);
191int branch_clk_set_parent(struct clk *clk, struct clk *parent);
192int branch_clk_is_enabled(struct clk *clk);
193void branch_clk_auto_off(struct clk *clk);
194int branch_clk_reset(struct clk *c, enum clk_reset_action action);
195
196/**
197 * struct measure_clk - for rate measurement debug use
198 * @sample_ticks: sample period in reference clock ticks
199 * @multiplier: measurement scale-up factor
200 * @divider: measurement scale-down factor
201 * @c: clk
202*/
203struct measure_clk {
204 uint64_t sample_ticks;
205 uint32_t multiplier;
206 uint32_t divider;
207 struct clk c;
208};
209
210extern struct clk_ops clk_ops_measure;
211
212static inline struct measure_clk *to_measure_clk(struct clk *clk)
213{
214 return container_of(clk, struct measure_clk, c);
215}
216
217/*
218 * clk_ops APIs
219 */
220int local_clk_enable(struct clk *c);
221void local_clk_disable(struct clk *c);
222int local_clk_set_rate(struct clk *c, unsigned rate);
223unsigned local_clk_get_rate(struct clk *c);
224int local_clk_is_enabled(struct clk *clk);
225long local_clk_round_rate(struct clk *c, unsigned rate);
226struct clk *local_clk_get_parent(struct clk *clk);
227
228/*
229 * Generic set-rate implementations
230 */
231void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
232void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
233void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf);
234#endif