2 * Copyright 2013 Broadcom Corporation.
4 * SPDX-License-Identifier: GPL-2.0+
9 * bcm235xx architecture clock framework
15 #include <asm/errno.h>
17 #include <asm/arch/sysmap.h>
18 #include <asm/kona-common/clk.h>
21 #define CLK_WR_ACCESS_PASSWORD 0x00a5a501
22 #define WR_ACCESS_OFFSET 0 /* common to all clock blocks */
23 #define POLICY_CTL_GO 1 /* Load and refresh policy masks */
24 #define POLICY_CTL_GO_ATL 4 /* Active Load */
27 int clk_get_and_enable(char *clkstr)
32 debug("%s: %s\n", __func__, clkstr);
40 printf("%s: Couldn't find %s\n", __func__, clkstr);
47 * Poll a register in a CCU's address space, returning when the
48 * specified bit in that register's value is set (or clear). Delay
49 * a microsecond after each read of the register. Returns true if
50 * successful, or false if we gave up trying.
52 * Caller must ensure the CCU lock is held.
54 #define CLK_GATE_DELAY_USEC 2000
55 static inline int wait_bit(void *base, u32 offset, u32 bit, bool want)
58 u32 bit_mask = 1 << bit;
60 for (tries = 0; tries < CLK_GATE_DELAY_USEC; tries++) {
64 val = readl(base + offset);
65 bit_val = (val & bit_mask) ? 1 : 0;
67 return 0; /* success */
71 debug("%s: timeout on addr 0x%p, waiting for bit %d to go to %d\n",
72 __func__, base + offset, bit, want);
77 /* Enable a peripheral clock */
78 static int peri_clk_enable(struct clk *c, int enable)
82 struct peri_clock *peri_clk = to_peri_clk(c);
83 struct peri_clk_data *cd = peri_clk->data;
84 struct bcm_clk_gate *gate = &cd->gate;
85 void *base = (void *)c->ccu_clk_mgr_base;
88 debug("%s: %s\n", __func__, c->name);
90 clk_get_rate(c); /* Make sure rate and sel are filled in */
93 writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
96 debug("%s %s set rate %lu div %lu sel %d parent %lu\n",
97 __func__, c->name, c->rate, c->div, c->sel,
101 * clkgate - only software controllable gates are
102 * supported by u-boot which includes all clocks
103 * that matter. This avoids bringing in a lot of extra
104 * complexity as done in the kernel framework.
106 if (gate_exists(gate)) {
107 reg = readl(base + cd->gate.offset);
108 reg |= (1 << cd->gate.en_bit);
109 writel(reg, base + cd->gate.offset);
112 /* div and pll select */
113 if (divider_exists(&cd->div)) {
114 reg = readl(base + cd->div.offset);
115 bitfield_replace(reg, cd->div.shift, cd->div.width,
117 writel(reg, base + cd->div.offset);
120 /* frequency selector */
121 if (selector_exists(&cd->sel)) {
122 reg = readl(base + cd->sel.offset);
123 bitfield_replace(reg, cd->sel.shift, cd->sel.width,
125 writel(reg, base + cd->sel.offset);
129 if (trigger_exists(&cd->trig)) {
130 writel((1 << cd->trig.bit), base + cd->trig.offset);
132 /* wait for trigger status bit to go to 0 */
133 ret = wait_bit(base, cd->trig.offset, cd->trig.bit, 0);
138 /* wait for running (status_bit = 1) */
139 ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 1);
143 debug("%s disable clock %s\n", __func__, c->name);
146 reg = readl(base + cd->gate.offset);
147 reg &= ~(1 << cd->gate.en_bit);
148 writel(reg, base + cd->gate.offset);
150 /* wait for stop (status_bit = 0) */
151 ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 0);
155 writel(0, base + WR_ACCESS_OFFSET);
160 /* Set the rate of a peripheral clock */
161 static int peri_clk_set_rate(struct clk *c, unsigned long rate)
166 unsigned long new_rate = 0, div = 1;
167 struct peri_clock *peri_clk = to_peri_clk(c);
168 struct peri_clk_data *cd = peri_clk->data;
171 debug("%s: %s\n", __func__, c->name);
175 for (clock = cd->clocks; *clock; clock++, i++) {
176 struct refclk *ref = refclk_str_to_clk(*clock);
178 printf("%s: Lookup of %s failed\n", __func__, *clock);
182 /* round to the new rate */
183 div = ref->clk.rate / rate;
187 new_rate = ref->clk.rate / div;
189 /* get the min diff */
190 if (abs(new_rate - rate) < diff) {
191 diff = abs(new_rate - rate);
193 c->parent = &ref->clk;
199 debug("%s %s set rate %lu div %lu sel %d parent %lu\n", __func__,
200 c->name, c->rate, c->div, c->sel, c->parent->rate);
204 /* Get the rate of a peripheral clock */
205 static unsigned long peri_clk_get_rate(struct clk *c)
207 struct peri_clock *peri_clk = to_peri_clk(c);
208 struct peri_clk_data *cd = peri_clk->data;
209 void *base = (void *)c->ccu_clk_mgr_base;
215 debug("%s: %s\n", __func__, c->name);
216 if (selector_exists(&cd->sel)) {
217 reg = readl(base + cd->sel.offset);
218 c->sel = bitfield_extract(reg, cd->sel.shift, cd->sel.width);
221 * For peri clocks that don't have a selector, the single
222 * reference clock will always exist at index 0.
227 if (divider_exists(&cd->div)) {
228 reg = readl(base + cd->div.offset);
229 div = bitfield_extract(reg, cd->div.shift, cd->div.width);
234 ref = refclk_str_to_clk(clock[c->sel]);
236 printf("%s: Can't lookup %s\n", __func__, clock[c->sel]);
240 c->parent = &ref->clk;
242 c->rate = c->parent->rate / c->div;
243 debug("%s parent rate %lu div %d sel %d rate %lu\n", __func__,
244 c->parent->rate, div, c->sel, c->rate);
249 /* Peripheral clock operations */
250 struct clk_ops peri_clk_ops = {
251 .enable = peri_clk_enable,
252 .set_rate = peri_clk_set_rate,
253 .get_rate = peri_clk_get_rate,
256 /* Enable a CCU clock */
257 static int ccu_clk_enable(struct clk *c, int enable)
259 struct ccu_clock *ccu_clk = to_ccu_clk(c);
260 void *base = (void *)c->ccu_clk_mgr_base;
264 debug("%s: %s\n", __func__, c->name);
266 return -EINVAL; /* CCU clock cannot shutdown */
269 writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
271 /* config enable for policy engine */
272 writel(1, base + ccu_clk->lvm_en_offset);
274 /* wait for bit to go to 0 */
275 ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0);
280 if (!ccu_clk->freq_bit_shift)
281 ccu_clk->freq_bit_shift = 8;
283 /* Set frequency id for each of the 4 policies */
284 reg = ccu_clk->freq_id |
285 (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) |
286 (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) |
287 (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3));
288 writel(reg, base + ccu_clk->policy_freq_offset);
290 /* enable all clock mask */
291 writel(0x7fffffff, base + ccu_clk->policy0_mask_offset);
292 writel(0x7fffffff, base + ccu_clk->policy1_mask_offset);
293 writel(0x7fffffff, base + ccu_clk->policy2_mask_offset);
294 writel(0x7fffffff, base + ccu_clk->policy3_mask_offset);
296 if (ccu_clk->num_policy_masks == 2) {
297 writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset);
298 writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset);
299 writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset);
300 writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset);
303 /* start policy engine */
304 reg = readl(base + ccu_clk->policy_ctl_offset);
305 reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL);
306 writel(reg, base + ccu_clk->policy_ctl_offset);
308 /* wait till started */
309 ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0);
314 writel(0, base + WR_ACCESS_OFFSET);
319 /* Get the CCU clock rate */
320 static unsigned long ccu_clk_get_rate(struct clk *c)
322 struct ccu_clock *ccu_clk = to_ccu_clk(c);
323 debug("%s: %s\n", __func__, c->name);
324 c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id];
328 /* CCU clock operations */
329 struct clk_ops ccu_clk_ops = {
330 .enable = ccu_clk_enable,
331 .get_rate = ccu_clk_get_rate,
334 /* Enable a bus clock */
335 static int bus_clk_enable(struct clk *c, int enable)
337 struct bus_clock *bus_clk = to_bus_clk(c);
338 struct bus_clk_data *cd = bus_clk->data;
339 void *base = (void *)c->ccu_clk_mgr_base;
343 debug("%s: %s\n", __func__, c->name);
345 writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
348 reg = readl(base + cd->gate.offset);
349 if (!!(reg & (1 << cd->gate.status_bit)) == !!enable)
350 debug("%s already %s\n", c->name,
351 enable ? "enabled" : "disabled");
353 int want = (enable) ? 1 : 0;
354 reg |= (1 << cd->gate.hw_sw_sel_bit);
357 reg |= (1 << cd->gate.en_bit);
359 reg &= ~(1 << cd->gate.en_bit);
361 writel(reg, base + cd->gate.offset);
362 ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit,
369 writel(0, base + WR_ACCESS_OFFSET);
374 /* Get the rate of a bus clock */
375 static unsigned long bus_clk_get_rate(struct clk *c)
377 struct bus_clock *bus_clk = to_bus_clk(c);
378 struct ccu_clock *ccu_clk;
380 debug("%s: %s\n", __func__, c->name);
381 ccu_clk = to_ccu_clk(c->parent);
383 c->rate = bus_clk->freq_tbl[ccu_clk->freq_id];
384 c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate;
388 /* Bus clock operations */
389 struct clk_ops bus_clk_ops = {
390 .enable = bus_clk_enable,
391 .get_rate = bus_clk_get_rate,
394 /* Enable a reference clock */
395 static int ref_clk_enable(struct clk *c, int enable)
397 debug("%s: %s\n", __func__, c->name);
401 /* Reference clock operations */
402 struct clk_ops ref_clk_ops = {
403 .enable = ref_clk_enable,
407 * clk.h implementation follows
410 /* Initialize the clock framework */
413 debug("%s:\n", __func__);
417 /* Get a clock handle, give a name string */
418 struct clk *clk_get(const char *con_id)
421 struct clk_lookup *clk_tblp;
423 debug("%s: %s\n", __func__, con_id);
425 clk_tblp = arch_clk_tbl;
426 for (i = 0; i < arch_clk_tbl_array_size; i++, clk_tblp++) {
427 if (clk_tblp->con_id) {
428 if (!con_id || strcmp(clk_tblp->con_id, con_id))
430 return clk_tblp->clk;
437 int clk_enable(struct clk *c)
441 debug("%s: %s\n", __func__, c->name);
442 if (!c->ops || !c->ops->enable)
445 /* enable parent clock first */
447 ret = clk_enable(c->parent);
453 ret = c->ops->enable(c, 1);
459 /* Disable a clock */
460 void clk_disable(struct clk *c)
462 debug("%s: %s\n", __func__, c->name);
463 if (!c->ops || !c->ops->enable)
466 if (c->use_cnt > 0) {
469 c->ops->enable(c, 0);
474 clk_disable(c->parent);
477 /* Get the clock rate */
478 unsigned long clk_get_rate(struct clk *c)
482 debug("%s: %s\n", __func__, c->name);
483 if (!c || !c->ops || !c->ops->get_rate)
486 rate = c->ops->get_rate(c);
487 debug("%s: rate = %ld\n", __func__, rate);
491 /* Set the clock rate */
492 int clk_set_rate(struct clk *c, unsigned long rate)
496 debug("%s: %s rate=%ld\n", __func__, c->name, rate);
497 if (!c || !c->ops || !c->ops->set_rate)
503 ret = c->ops->set_rate(c, rate);
508 /* Not required for this arch */
510 long clk_round_rate(struct clk *clk, unsigned long rate);
511 int clk_set_parent(struct clk *clk, struct clk *parent);
512 struct clk *clk_get_parent(struct clk *clk);