blob: f996214e19651dd6474340240fcdd3a515bdc5c5 [file] [log] [blame]
Shashank Mittal30262902012-02-21 15:37:24 -08001/*
Duy Truongf3ac7b32013-02-13 01:07:28 -08002 * Copyright (c) 2012, 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#include <stdint.h>
30#include <debug.h>
31#include <reg.h>
32#include <err.h>
33#include <limits.h>
34#include <bits.h>
35#include <clock.h>
36#include <clock-local.h>
Amol Jadic2c941c2012-06-22 00:02:01 -070037#include <platform/timer.h>
Shashank Mittal30262902012-02-21 15:37:24 -080038
39/*
40 * When enabling/disabling a clock, check the halt bit up to this number
41 * number of times (with a 1 us delay in between) before continuing.
42 */
43#define HALT_CHECK_MAX_LOOPS 100
44/* For clock without halt checking, wait this long after enables/disables. */
45#define HALT_CHECK_DELAY_US 10
46
47struct clk_freq_tbl local_dummy_freq = F_END;
48
49/*
50 * Clock enable/disable functions
51 */
52static int branch_clk_is_halted(const struct branch *clk)
53{
54 int invert = (clk->halt_check == ENABLE);
55 int status_bit = readl_relaxed(clk->halt_reg) & BIT(clk->halt_bit);
56 return invert ? !status_bit : status_bit;
57}
58
59static void __branch_clk_enable_reg(const struct branch *clk, const char *name)
60{
61 uint32_t reg_val;
62
63 if (clk->en_mask) {
64 reg_val = readl_relaxed(clk->ctl_reg);
65 reg_val |= clk->en_mask;
66 writel_relaxed(reg_val, clk->ctl_reg);
67 }
68
69 /* Wait for clock to enable before returning. */
70 if (clk->halt_check == DELAY)
71 udelay(HALT_CHECK_DELAY_US);
72 else if (clk->halt_check == ENABLE || clk->halt_check == HALT
73 || clk->halt_check == ENABLE_VOTED
74 || clk->halt_check == HALT_VOTED) {
75 int count;
76
77 /* Wait up to HALT_CHECK_MAX_LOOPS for clock to enable. */
78 for (count = HALT_CHECK_MAX_LOOPS; branch_clk_is_halted(clk)
79 && count > 0; count--)
80 udelay(1);
81 }
82}
83
84/* Perform any register operations required to enable the clock. */
85static void __local_clk_enable_reg(struct rcg_clk *clk)
86{
87 uint32_t reg_val;
88
89 void *const reg = clk->b.ctl_reg;
90
91 if(clk->current_freq == &local_dummy_freq)
92 dprintf(CRITICAL, "Attempting to enable %s before setting its rate.", clk->c.dbg_name);
93 /*
94 * Program the NS register, if applicable. NS registers are not
95 * set in the set_rate path because power can be saved by deferring
96 * the selection of a clocked source until the clock is enabled.
97 */
98 if (clk->ns_mask) {
99 reg_val = readl_relaxed(clk->ns_reg);
100 reg_val &= ~(clk->ns_mask);
101 reg_val |= (clk->current_freq->ns_val & clk->ns_mask);
102 writel_relaxed(reg_val, clk->ns_reg);
103 }
104
105 /* Enable MN counter, if applicable. */
106 reg_val = readl_relaxed(reg);
107 if (clk->current_freq->mnd_en_mask) {
108 reg_val |= clk->current_freq->mnd_en_mask;
109 writel_relaxed(reg_val, reg);
110 }
111 /* Enable root. */
112 if (clk->root_en_mask) {
113 reg_val |= clk->root_en_mask;
114 writel_relaxed(reg_val, reg);
115 }
116 __branch_clk_enable_reg(&clk->b, clk->c.dbg_name);
117}
118
119/* Enable a clock and any related power rail. */
120int local_clk_enable(struct clk *c)
121{
122 int rc;
123 struct clk_freq_tbl *cf;
124 struct rcg_clk *clk = to_rcg_clk(c);
125
126 cf = clk->current_freq;
127 rc = clk_enable(clk->depends);
128 if (rc)
129 goto err_dep;
130 __local_clk_enable_reg(clk);
131 clk->enabled = true;
132err_dep:
133 return rc;
134}
135
136/* Disable a clock and any related power rail. */
137void local_clk_disable(struct clk *c)
138{
139 /*TODO: Stub function for now.*/
140}
141
142/*
143 * Frequency-related functions
144 */
145
146/* Set a clock's frequency. */
147static int _local_clk_set_rate(struct rcg_clk *clk, struct clk_freq_tbl *nf)
148{
149 struct clk_freq_tbl *cf;
150 int rc = 0;
151
152 /* Check if frequency is actually changed. */
153 cf = clk->current_freq;
154 if (nf == cf)
155 goto unlock;
156
157 if (clk->enabled) {
158 rc = clk_enable(nf->src_clk);
159 if (rc) {
160 goto unlock;
161 }
162 }
163
164 /* Perform clock-specific frequency switch operations. */
165 ASSERT(clk->set_rate);
166 clk->set_rate(clk, nf);
167
168 /*
169 * Current freq must be updated before __local_clk_enable_reg()
170 * is called to make sure the MNCNTR_EN bit is set correctly.
171 */
172 clk->current_freq = nf;
173
174 /* Enable any clocks that were disabled. */
175 if (clk->bank_masks == NULL) {
176 if (clk->enabled)
177 __local_clk_enable_reg(clk);
178 }
179
180unlock:
181 return rc;
182}
183
184/* Set a clock to an exact rate. */
185int local_clk_set_rate(struct clk *c, unsigned rate)
186{
187 struct rcg_clk *clk = to_rcg_clk(c);
188 struct clk_freq_tbl *nf;
189
190 for (nf = clk->freq_tbl; nf->freq_hz != FREQ_END
191 && nf->freq_hz != rate; nf++)
192 ;
193
194 if (nf->freq_hz == FREQ_END)
195 return ERR_INVALID_ARGS;
196
197 return _local_clk_set_rate(clk, nf);
198}
199
200/* Get the currently-set rate of a clock in Hz. */
201unsigned local_clk_get_rate(struct clk *c)
202{
203 /* TODO: Stub function for now. */
204 return 0;
205}
206
207/* Check if a clock is currently enabled. */
208int local_clk_is_enabled(struct clk *clk)
209{
210 return to_rcg_clk(clk)->enabled;
211}
212
213/* Return a supported rate that's at least the specified rate. */
214long local_clk_round_rate(struct clk *c, unsigned rate)
215{
216 struct rcg_clk *clk = to_rcg_clk(c);
217 struct clk_freq_tbl *f;
218
219 for (f = clk->freq_tbl; f->freq_hz != FREQ_END; f++)
220 if (f->freq_hz >= rate)
221 return f->freq_hz;
222
223 return ERR_INVALID_ARGS;
224}
225
226struct clk *local_clk_get_parent(struct clk *clk)
227{
228 return to_rcg_clk(clk)->current_freq->src_clk;
229}
230
231/*
Shashank Mittal30262902012-02-21 15:37:24 -0800232 * Branch clocks functions
233 */
234int branch_clk_enable(struct clk *clk)
235{
236 struct branch_clk *branch = to_branch_clk(clk);
237
238 __branch_clk_enable_reg(&branch->b, branch->c.dbg_name);
239 branch->enabled = true;
240
241 return 0;
242}
243
244void branch_clk_disable(struct clk *clk)
245{
246 struct branch_clk *branch = to_branch_clk(clk);
247
248 /* TODO: Stub function for now */
249}
250
251struct clk *branch_clk_get_parent(struct clk *clk)
252{
253 struct branch_clk *branch = to_branch_clk(clk);
254 return branch->parent;
255}
256
257int branch_clk_set_parent(struct clk *clk, struct clk *parent)
258{
259 /* This is a stub function. */
260 return 0;
261}
262
263int branch_clk_is_enabled(struct clk *clk)
264{
265 struct branch_clk *branch = to_branch_clk(clk);
266 return branch->enabled;
267}
268
269/**/
270/* For clocks with MND dividers. */
271void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf)
272{
273 uint32_t ns_reg_val, ctl_reg_val;
274
275 /* Assert MND reset. */
276 ns_reg_val = readl_relaxed(clk->ns_reg);
277 ns_reg_val |= BIT(7);
278 writel_relaxed(ns_reg_val, clk->ns_reg);
279
280 /* Program M and D values. */
281 writel_relaxed(nf->md_val, clk->md_reg);
282
283 /* If the clock has a separate CC register, program it. */
284 if (clk->ns_reg != clk->b.ctl_reg) {
285 ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
286 ctl_reg_val &= ~(clk->ctl_mask);
287 ctl_reg_val |= nf->ctl_val;
288 writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
289 }
290
291 /* Deassert MND reset. */
292 ns_reg_val &= ~BIT(7);
293 writel_relaxed(ns_reg_val, clk->ns_reg);
294}
295
296void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf)
297{
298 struct bank_masks *banks = clk->bank_masks;
299 const struct bank_mask_info *new_bank_masks;
300 const struct bank_mask_info *old_bank_masks;
301 uint32_t ns_reg_val, ctl_reg_val;
302 uint32_t bank_sel;
303
304 /*
305 * Determine active bank and program the other one. If the clock is
306 * off, program the active bank since bank switching won't work if
307 * both banks aren't running.
308 */
309 ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
310 bank_sel = !!(ctl_reg_val & banks->bank_sel_mask);
311
312 /* If clock isn't running, don't switch banks. */
313 bank_sel ^= (!clk->enabled || clk->current_freq->freq_hz == 0);
314 if (bank_sel == 0) {
315 new_bank_masks = &banks->bank1_mask;
316 old_bank_masks = &banks->bank0_mask;
317 } else {
318 new_bank_masks = &banks->bank0_mask;
319 old_bank_masks = &banks->bank1_mask;
320 }
321
322 ns_reg_val = readl_relaxed(clk->ns_reg);
323
324 /* Assert bank MND reset. */
325 ns_reg_val |= new_bank_masks->rst_mask;
326 writel_relaxed(ns_reg_val, clk->ns_reg);
327
328 /*
329 * Program NS only if the clock is enabled, since the NS will be set
330 * as part of the enable procedure and should remain with a low-power
331 * MUX input selected until then.
332 */
333 if (clk->enabled) {
334 ns_reg_val &= ~(new_bank_masks->ns_mask);
335 ns_reg_val |= (nf->ns_val & new_bank_masks->ns_mask);
336 writel_relaxed(ns_reg_val, clk->ns_reg);
337 }
338
339 writel_relaxed(nf->md_val, new_bank_masks->md_reg);
340
341 /* Enable counter only if clock is enabled. */
342 if (clk->enabled)
343 ctl_reg_val |= new_bank_masks->mnd_en_mask;
344 else
345 ctl_reg_val &= ~(new_bank_masks->mnd_en_mask);
346
347 ctl_reg_val &= ~(new_bank_masks->mode_mask);
348 ctl_reg_val |= (nf->ctl_val & new_bank_masks->mode_mask);
349 writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
350
351 /* Deassert bank MND reset. */
352 ns_reg_val &= ~(new_bank_masks->rst_mask);
353 writel_relaxed(ns_reg_val, clk->ns_reg);
354
355 /*
356 * Switch to the new bank if clock is running. If it isn't, then
357 * no switch is necessary since we programmed the active bank.
358 */
359 if (clk->enabled && clk->current_freq->freq_hz) {
360 ctl_reg_val ^= banks->bank_sel_mask;
361 writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
362 /*
363 * Wait at least 6 cycles of slowest bank's clock
364 * for the glitch-free MUX to fully switch sources.
365 */
366 udelay(1);
367
368 /* Disable old bank's MN counter. */
369 ctl_reg_val &= ~(old_bank_masks->mnd_en_mask);
370 writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
371
372 /* Program old bank to a low-power source and divider. */
373 ns_reg_val &= ~(old_bank_masks->ns_mask);
374 ns_reg_val |= (clk->freq_tbl->ns_val & old_bank_masks->ns_mask);
375 writel_relaxed(ns_reg_val, clk->ns_reg);
376 }
377
378 /*
379 * If this freq requires the MN counter to be enabled,
380 * update the enable mask to match the current bank.
381 */
382 if (nf->mnd_en_mask)
383 nf->mnd_en_mask = new_bank_masks->mnd_en_mask;
384 /* Update the NS mask to match the current bank. */
385 clk->ns_mask = new_bank_masks->ns_mask;
386}
387
388void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf)
389{
390 /*
391 * Nothing to do for fixed-rate or integer-divider clocks. Any settings
392 * in NS registers are applied in the enable path, since power can be
393 * saved by leaving an un-clocked or slowly-clocked source selected
394 * until the clock is enabled.
395 */
396}
397