1989ce049SDarwin Rambo /*
2989ce049SDarwin Rambo * Copyright 2013 Broadcom Corporation.
3989ce049SDarwin Rambo *
4989ce049SDarwin Rambo * SPDX-License-Identifier: GPL-2.0+
5989ce049SDarwin Rambo */
6989ce049SDarwin Rambo
7989ce049SDarwin Rambo /*
8989ce049SDarwin Rambo *
9989ce049SDarwin Rambo * bcm281xx architecture clock framework
10989ce049SDarwin Rambo *
11989ce049SDarwin Rambo */
12989ce049SDarwin Rambo
13989ce049SDarwin Rambo #include <common.h>
14989ce049SDarwin Rambo #include <asm/io.h>
151221ce45SMasahiro Yamada #include <linux/errno.h>
16989ce049SDarwin Rambo #include <bitfield.h>
17989ce049SDarwin Rambo #include <asm/arch/sysmap.h>
18989ce049SDarwin Rambo #include <asm/kona-common/clk.h>
19989ce049SDarwin Rambo #include "clk-core.h"
20989ce049SDarwin Rambo
21989ce049SDarwin Rambo #define CLK_WR_ACCESS_PASSWORD 0x00a5a501
22989ce049SDarwin Rambo #define WR_ACCESS_OFFSET 0 /* common to all clock blocks */
23989ce049SDarwin Rambo #define POLICY_CTL_GO 1 /* Load and refresh policy masks */
24989ce049SDarwin Rambo #define POLICY_CTL_GO_ATL 4 /* Active Load */
25989ce049SDarwin Rambo
26989ce049SDarwin Rambo /* Helper function */
clk_get_and_enable(char * clkstr)27989ce049SDarwin Rambo int clk_get_and_enable(char *clkstr)
28989ce049SDarwin Rambo {
29989ce049SDarwin Rambo int ret = 0;
30989ce049SDarwin Rambo struct clk *c;
31989ce049SDarwin Rambo
32989ce049SDarwin Rambo debug("%s: %s\n", __func__, clkstr);
33989ce049SDarwin Rambo
34989ce049SDarwin Rambo c = clk_get(clkstr);
35989ce049SDarwin Rambo if (c) {
36989ce049SDarwin Rambo ret = clk_enable(c);
37989ce049SDarwin Rambo if (ret)
38989ce049SDarwin Rambo return ret;
39989ce049SDarwin Rambo } else {
40989ce049SDarwin Rambo printf("%s: Couldn't find %s\n", __func__, clkstr);
41989ce049SDarwin Rambo return -EINVAL;
42989ce049SDarwin Rambo }
43989ce049SDarwin Rambo return ret;
44989ce049SDarwin Rambo }
45989ce049SDarwin Rambo
46989ce049SDarwin Rambo /*
47989ce049SDarwin Rambo * Poll a register in a CCU's address space, returning when the
48989ce049SDarwin Rambo * specified bit in that register's value is set (or clear). Delay
49989ce049SDarwin Rambo * a microsecond after each read of the register. Returns true if
50989ce049SDarwin Rambo * successful, or false if we gave up trying.
51989ce049SDarwin Rambo *
52989ce049SDarwin Rambo * Caller must ensure the CCU lock is held.
53989ce049SDarwin Rambo */
54989ce049SDarwin Rambo #define CLK_GATE_DELAY_USEC 2000
wait_bit(void * base,u32 offset,u32 bit,bool want)55989ce049SDarwin Rambo static inline int wait_bit(void *base, u32 offset, u32 bit, bool want)
56989ce049SDarwin Rambo {
57989ce049SDarwin Rambo unsigned int tries;
58989ce049SDarwin Rambo u32 bit_mask = 1 << bit;
59989ce049SDarwin Rambo
60989ce049SDarwin Rambo for (tries = 0; tries < CLK_GATE_DELAY_USEC; tries++) {
61989ce049SDarwin Rambo u32 val;
62989ce049SDarwin Rambo bool bit_val;
63989ce049SDarwin Rambo
64989ce049SDarwin Rambo val = readl(base + offset);
65989ce049SDarwin Rambo bit_val = (val & bit_mask) ? 1 : 0;
66989ce049SDarwin Rambo if (bit_val == want)
67989ce049SDarwin Rambo return 0; /* success */
68989ce049SDarwin Rambo udelay(1);
69989ce049SDarwin Rambo }
70989ce049SDarwin Rambo
71989ce049SDarwin Rambo debug("%s: timeout on addr 0x%p, waiting for bit %d to go to %d\n",
72989ce049SDarwin Rambo __func__, base + offset, bit, want);
73989ce049SDarwin Rambo
74989ce049SDarwin Rambo return -ETIMEDOUT;
75989ce049SDarwin Rambo }
76989ce049SDarwin Rambo
77989ce049SDarwin Rambo /* Enable a peripheral clock */
peri_clk_enable(struct clk * c,int enable)78989ce049SDarwin Rambo static int peri_clk_enable(struct clk *c, int enable)
79989ce049SDarwin Rambo {
80989ce049SDarwin Rambo int ret = 0;
81989ce049SDarwin Rambo u32 reg;
82989ce049SDarwin Rambo struct peri_clock *peri_clk = to_peri_clk(c);
83989ce049SDarwin Rambo struct peri_clk_data *cd = peri_clk->data;
84989ce049SDarwin Rambo struct bcm_clk_gate *gate = &cd->gate;
85989ce049SDarwin Rambo void *base = (void *)c->ccu_clk_mgr_base;
86989ce049SDarwin Rambo
87989ce049SDarwin Rambo
88989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
89989ce049SDarwin Rambo
90989ce049SDarwin Rambo clk_get_rate(c); /* Make sure rate and sel are filled in */
91989ce049SDarwin Rambo
92989ce049SDarwin Rambo /* enable access */
93989ce049SDarwin Rambo writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
94989ce049SDarwin Rambo
95989ce049SDarwin Rambo if (enable) {
96989ce049SDarwin Rambo debug("%s %s set rate %lu div %lu sel %d parent %lu\n",
97989ce049SDarwin Rambo __func__, c->name, c->rate, c->div, c->sel,
98989ce049SDarwin Rambo c->parent->rate);
99989ce049SDarwin Rambo
100989ce049SDarwin Rambo /*
101989ce049SDarwin Rambo * clkgate - only software controllable gates are
102989ce049SDarwin Rambo * supported by u-boot which includes all clocks
103989ce049SDarwin Rambo * that matter. This avoids bringing in a lot of extra
104989ce049SDarwin Rambo * complexity as done in the kernel framework.
105989ce049SDarwin Rambo */
106989ce049SDarwin Rambo if (gate_exists(gate)) {
107989ce049SDarwin Rambo reg = readl(base + cd->gate.offset);
108989ce049SDarwin Rambo reg |= (1 << cd->gate.en_bit);
109989ce049SDarwin Rambo writel(reg, base + cd->gate.offset);
110989ce049SDarwin Rambo }
111989ce049SDarwin Rambo
112989ce049SDarwin Rambo /* div and pll select */
113989ce049SDarwin Rambo if (divider_exists(&cd->div)) {
114989ce049SDarwin Rambo reg = readl(base + cd->div.offset);
115989ce049SDarwin Rambo bitfield_replace(reg, cd->div.shift, cd->div.width,
116989ce049SDarwin Rambo c->div - 1);
117989ce049SDarwin Rambo writel(reg, base + cd->div.offset);
118989ce049SDarwin Rambo }
119989ce049SDarwin Rambo
120989ce049SDarwin Rambo /* frequency selector */
121989ce049SDarwin Rambo if (selector_exists(&cd->sel)) {
122989ce049SDarwin Rambo reg = readl(base + cd->sel.offset);
123989ce049SDarwin Rambo bitfield_replace(reg, cd->sel.shift, cd->sel.width,
124989ce049SDarwin Rambo c->sel);
125989ce049SDarwin Rambo writel(reg, base + cd->sel.offset);
126989ce049SDarwin Rambo }
127989ce049SDarwin Rambo
128989ce049SDarwin Rambo /* trigger */
129989ce049SDarwin Rambo if (trigger_exists(&cd->trig)) {
130989ce049SDarwin Rambo writel((1 << cd->trig.bit), base + cd->trig.offset);
131989ce049SDarwin Rambo
132989ce049SDarwin Rambo /* wait for trigger status bit to go to 0 */
133989ce049SDarwin Rambo ret = wait_bit(base, cd->trig.offset, cd->trig.bit, 0);
134989ce049SDarwin Rambo if (ret)
135989ce049SDarwin Rambo return ret;
136989ce049SDarwin Rambo }
137989ce049SDarwin Rambo
138989ce049SDarwin Rambo /* wait for running (status_bit = 1) */
139989ce049SDarwin Rambo ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 1);
140989ce049SDarwin Rambo if (ret)
141989ce049SDarwin Rambo return ret;
142989ce049SDarwin Rambo } else {
143989ce049SDarwin Rambo debug("%s disable clock %s\n", __func__, c->name);
144989ce049SDarwin Rambo
145989ce049SDarwin Rambo /* clkgate */
146989ce049SDarwin Rambo reg = readl(base + cd->gate.offset);
147989ce049SDarwin Rambo reg &= ~(1 << cd->gate.en_bit);
148989ce049SDarwin Rambo writel(reg, base + cd->gate.offset);
149989ce049SDarwin Rambo
150989ce049SDarwin Rambo /* wait for stop (status_bit = 0) */
151989ce049SDarwin Rambo ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit, 0);
152989ce049SDarwin Rambo }
153989ce049SDarwin Rambo
154989ce049SDarwin Rambo /* disable access */
155989ce049SDarwin Rambo writel(0, base + WR_ACCESS_OFFSET);
156989ce049SDarwin Rambo
157989ce049SDarwin Rambo return ret;
158989ce049SDarwin Rambo }
159989ce049SDarwin Rambo
160989ce049SDarwin Rambo /* Set the rate of a peripheral clock */
peri_clk_set_rate(struct clk * c,unsigned long rate)161989ce049SDarwin Rambo static int peri_clk_set_rate(struct clk *c, unsigned long rate)
162989ce049SDarwin Rambo {
163989ce049SDarwin Rambo int ret = 0;
164989ce049SDarwin Rambo int i;
165989ce049SDarwin Rambo unsigned long diff;
166989ce049SDarwin Rambo unsigned long new_rate = 0, div = 1;
167989ce049SDarwin Rambo struct peri_clock *peri_clk = to_peri_clk(c);
168989ce049SDarwin Rambo struct peri_clk_data *cd = peri_clk->data;
169989ce049SDarwin Rambo const char **clock;
170989ce049SDarwin Rambo
171989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
172989ce049SDarwin Rambo diff = rate;
173989ce049SDarwin Rambo
174989ce049SDarwin Rambo i = 0;
175989ce049SDarwin Rambo for (clock = cd->clocks; *clock; clock++, i++) {
176989ce049SDarwin Rambo struct refclk *ref = refclk_str_to_clk(*clock);
177989ce049SDarwin Rambo if (!ref) {
178989ce049SDarwin Rambo printf("%s: Lookup of %s failed\n", __func__, *clock);
179989ce049SDarwin Rambo return -EINVAL;
180989ce049SDarwin Rambo }
181989ce049SDarwin Rambo
182989ce049SDarwin Rambo /* round to the new rate */
183989ce049SDarwin Rambo div = ref->clk.rate / rate;
184989ce049SDarwin Rambo if (div == 0)
185989ce049SDarwin Rambo div = 1;
186989ce049SDarwin Rambo
187989ce049SDarwin Rambo new_rate = ref->clk.rate / div;
188989ce049SDarwin Rambo
189989ce049SDarwin Rambo /* get the min diff */
190989ce049SDarwin Rambo if (abs(new_rate - rate) < diff) {
191989ce049SDarwin Rambo diff = abs(new_rate - rate);
192989ce049SDarwin Rambo c->sel = i;
193989ce049SDarwin Rambo c->parent = &ref->clk;
194989ce049SDarwin Rambo c->rate = new_rate;
195989ce049SDarwin Rambo c->div = div;
196989ce049SDarwin Rambo }
197989ce049SDarwin Rambo }
198989ce049SDarwin Rambo
199989ce049SDarwin Rambo debug("%s %s set rate %lu div %lu sel %d parent %lu\n", __func__,
200989ce049SDarwin Rambo c->name, c->rate, c->div, c->sel, c->parent->rate);
201989ce049SDarwin Rambo return ret;
202989ce049SDarwin Rambo }
203989ce049SDarwin Rambo
204989ce049SDarwin Rambo /* Get the rate of a peripheral clock */
peri_clk_get_rate(struct clk * c)205989ce049SDarwin Rambo static unsigned long peri_clk_get_rate(struct clk *c)
206989ce049SDarwin Rambo {
207989ce049SDarwin Rambo struct peri_clock *peri_clk = to_peri_clk(c);
208989ce049SDarwin Rambo struct peri_clk_data *cd = peri_clk->data;
209989ce049SDarwin Rambo void *base = (void *)c->ccu_clk_mgr_base;
210989ce049SDarwin Rambo int div = 1;
211989ce049SDarwin Rambo const char **clock;
212989ce049SDarwin Rambo struct refclk *ref;
213989ce049SDarwin Rambo u32 reg;
214989ce049SDarwin Rambo
215989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
216989ce049SDarwin Rambo if (selector_exists(&cd->sel)) {
217989ce049SDarwin Rambo reg = readl(base + cd->sel.offset);
218989ce049SDarwin Rambo c->sel = bitfield_extract(reg, cd->sel.shift, cd->sel.width);
219989ce049SDarwin Rambo } else {
220989ce049SDarwin Rambo /*
221989ce049SDarwin Rambo * For peri clocks that don't have a selector, the single
222989ce049SDarwin Rambo * reference clock will always exist at index 0.
223989ce049SDarwin Rambo */
224989ce049SDarwin Rambo c->sel = 0;
225989ce049SDarwin Rambo }
226989ce049SDarwin Rambo
227989ce049SDarwin Rambo if (divider_exists(&cd->div)) {
228989ce049SDarwin Rambo reg = readl(base + cd->div.offset);
229989ce049SDarwin Rambo div = bitfield_extract(reg, cd->div.shift, cd->div.width);
230989ce049SDarwin Rambo div += 1;
231989ce049SDarwin Rambo }
232989ce049SDarwin Rambo
233989ce049SDarwin Rambo clock = cd->clocks;
234989ce049SDarwin Rambo ref = refclk_str_to_clk(clock[c->sel]);
235989ce049SDarwin Rambo if (!ref) {
236989ce049SDarwin Rambo printf("%s: Can't lookup %s\n", __func__, clock[c->sel]);
237989ce049SDarwin Rambo return 0;
238989ce049SDarwin Rambo }
239989ce049SDarwin Rambo
240989ce049SDarwin Rambo c->parent = &ref->clk;
241989ce049SDarwin Rambo c->div = div;
242989ce049SDarwin Rambo c->rate = c->parent->rate / c->div;
243989ce049SDarwin Rambo debug("%s parent rate %lu div %d sel %d rate %lu\n", __func__,
244989ce049SDarwin Rambo c->parent->rate, div, c->sel, c->rate);
245989ce049SDarwin Rambo
246989ce049SDarwin Rambo return c->rate;
247989ce049SDarwin Rambo }
248989ce049SDarwin Rambo
249989ce049SDarwin Rambo /* Peripheral clock operations */
250989ce049SDarwin Rambo struct clk_ops peri_clk_ops = {
251989ce049SDarwin Rambo .enable = peri_clk_enable,
252989ce049SDarwin Rambo .set_rate = peri_clk_set_rate,
253989ce049SDarwin Rambo .get_rate = peri_clk_get_rate,
254989ce049SDarwin Rambo };
255989ce049SDarwin Rambo
256989ce049SDarwin Rambo /* Enable a CCU clock */
ccu_clk_enable(struct clk * c,int enable)257989ce049SDarwin Rambo static int ccu_clk_enable(struct clk *c, int enable)
258989ce049SDarwin Rambo {
259989ce049SDarwin Rambo struct ccu_clock *ccu_clk = to_ccu_clk(c);
260989ce049SDarwin Rambo void *base = (void *)c->ccu_clk_mgr_base;
261989ce049SDarwin Rambo int ret = 0;
262989ce049SDarwin Rambo u32 reg;
263989ce049SDarwin Rambo
264989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
265989ce049SDarwin Rambo if (!enable)
266989ce049SDarwin Rambo return -EINVAL; /* CCU clock cannot shutdown */
267989ce049SDarwin Rambo
268989ce049SDarwin Rambo /* enable access */
269989ce049SDarwin Rambo writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
270989ce049SDarwin Rambo
271989ce049SDarwin Rambo /* config enable for policy engine */
272989ce049SDarwin Rambo writel(1, base + ccu_clk->lvm_en_offset);
273989ce049SDarwin Rambo
274989ce049SDarwin Rambo /* wait for bit to go to 0 */
275989ce049SDarwin Rambo ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0);
276989ce049SDarwin Rambo if (ret)
277989ce049SDarwin Rambo return ret;
278989ce049SDarwin Rambo
279989ce049SDarwin Rambo /* freq ID */
280989ce049SDarwin Rambo if (!ccu_clk->freq_bit_shift)
281989ce049SDarwin Rambo ccu_clk->freq_bit_shift = 8;
282989ce049SDarwin Rambo
283989ce049SDarwin Rambo /* Set frequency id for each of the 4 policies */
284989ce049SDarwin Rambo reg = ccu_clk->freq_id |
285989ce049SDarwin Rambo (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) |
286989ce049SDarwin Rambo (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) |
287989ce049SDarwin Rambo (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3));
288989ce049SDarwin Rambo writel(reg, base + ccu_clk->policy_freq_offset);
289989ce049SDarwin Rambo
290989ce049SDarwin Rambo /* enable all clock mask */
291989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy0_mask_offset);
292989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy1_mask_offset);
293989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy2_mask_offset);
294989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy3_mask_offset);
295989ce049SDarwin Rambo
296989ce049SDarwin Rambo if (ccu_clk->num_policy_masks == 2) {
297989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset);
298989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset);
299989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset);
300989ce049SDarwin Rambo writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset);
301989ce049SDarwin Rambo }
302989ce049SDarwin Rambo
303989ce049SDarwin Rambo /* start policy engine */
304989ce049SDarwin Rambo reg = readl(base + ccu_clk->policy_ctl_offset);
305989ce049SDarwin Rambo reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL);
306989ce049SDarwin Rambo writel(reg, base + ccu_clk->policy_ctl_offset);
307989ce049SDarwin Rambo
308989ce049SDarwin Rambo /* wait till started */
309989ce049SDarwin Rambo ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0);
310989ce049SDarwin Rambo if (ret)
311989ce049SDarwin Rambo return ret;
312989ce049SDarwin Rambo
313989ce049SDarwin Rambo /* disable access */
314989ce049SDarwin Rambo writel(0, base + WR_ACCESS_OFFSET);
315989ce049SDarwin Rambo
316989ce049SDarwin Rambo return ret;
317989ce049SDarwin Rambo }
318989ce049SDarwin Rambo
319989ce049SDarwin Rambo /* Get the CCU clock rate */
ccu_clk_get_rate(struct clk * c)320989ce049SDarwin Rambo static unsigned long ccu_clk_get_rate(struct clk *c)
321989ce049SDarwin Rambo {
322989ce049SDarwin Rambo struct ccu_clock *ccu_clk = to_ccu_clk(c);
323989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
324989ce049SDarwin Rambo c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id];
325989ce049SDarwin Rambo return c->rate;
326989ce049SDarwin Rambo }
327989ce049SDarwin Rambo
328989ce049SDarwin Rambo /* CCU clock operations */
329989ce049SDarwin Rambo struct clk_ops ccu_clk_ops = {
330989ce049SDarwin Rambo .enable = ccu_clk_enable,
331989ce049SDarwin Rambo .get_rate = ccu_clk_get_rate,
332989ce049SDarwin Rambo };
333989ce049SDarwin Rambo
334989ce049SDarwin Rambo /* Enable a bus clock */
bus_clk_enable(struct clk * c,int enable)335989ce049SDarwin Rambo static int bus_clk_enable(struct clk *c, int enable)
336989ce049SDarwin Rambo {
337989ce049SDarwin Rambo struct bus_clock *bus_clk = to_bus_clk(c);
338989ce049SDarwin Rambo struct bus_clk_data *cd = bus_clk->data;
339989ce049SDarwin Rambo void *base = (void *)c->ccu_clk_mgr_base;
340989ce049SDarwin Rambo int ret = 0;
341989ce049SDarwin Rambo u32 reg;
342989ce049SDarwin Rambo
343989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
344989ce049SDarwin Rambo /* enable access */
345989ce049SDarwin Rambo writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);
346989ce049SDarwin Rambo
347989ce049SDarwin Rambo /* enable gating */
348989ce049SDarwin Rambo reg = readl(base + cd->gate.offset);
349989ce049SDarwin Rambo if (!!(reg & (1 << cd->gate.status_bit)) == !!enable)
350989ce049SDarwin Rambo debug("%s already %s\n", c->name,
351989ce049SDarwin Rambo enable ? "enabled" : "disabled");
352989ce049SDarwin Rambo else {
353989ce049SDarwin Rambo int want = (enable) ? 1 : 0;
354989ce049SDarwin Rambo reg |= (1 << cd->gate.hw_sw_sel_bit);
355989ce049SDarwin Rambo
356989ce049SDarwin Rambo if (enable)
357989ce049SDarwin Rambo reg |= (1 << cd->gate.en_bit);
358989ce049SDarwin Rambo else
359989ce049SDarwin Rambo reg &= ~(1 << cd->gate.en_bit);
360989ce049SDarwin Rambo
361989ce049SDarwin Rambo writel(reg, base + cd->gate.offset);
362989ce049SDarwin Rambo ret = wait_bit(base, cd->gate.offset, cd->gate.status_bit,
363989ce049SDarwin Rambo want);
364989ce049SDarwin Rambo if (ret)
365989ce049SDarwin Rambo return ret;
366989ce049SDarwin Rambo }
367989ce049SDarwin Rambo
368989ce049SDarwin Rambo /* disable access */
369989ce049SDarwin Rambo writel(0, base + WR_ACCESS_OFFSET);
370989ce049SDarwin Rambo
371989ce049SDarwin Rambo return ret;
372989ce049SDarwin Rambo }
373989ce049SDarwin Rambo
374989ce049SDarwin Rambo /* Get the rate of a bus clock */
bus_clk_get_rate(struct clk * c)375989ce049SDarwin Rambo static unsigned long bus_clk_get_rate(struct clk *c)
376989ce049SDarwin Rambo {
377989ce049SDarwin Rambo struct bus_clock *bus_clk = to_bus_clk(c);
378989ce049SDarwin Rambo struct ccu_clock *ccu_clk;
379989ce049SDarwin Rambo
380989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
381989ce049SDarwin Rambo ccu_clk = to_ccu_clk(c->parent);
382989ce049SDarwin Rambo
383989ce049SDarwin Rambo c->rate = bus_clk->freq_tbl[ccu_clk->freq_id];
384989ce049SDarwin Rambo c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate;
385989ce049SDarwin Rambo return c->rate;
386989ce049SDarwin Rambo }
387989ce049SDarwin Rambo
388989ce049SDarwin Rambo /* Bus clock operations */
389989ce049SDarwin Rambo struct clk_ops bus_clk_ops = {
390989ce049SDarwin Rambo .enable = bus_clk_enable,
391989ce049SDarwin Rambo .get_rate = bus_clk_get_rate,
392989ce049SDarwin Rambo };
393989ce049SDarwin Rambo
394989ce049SDarwin Rambo /* Enable a reference clock */
ref_clk_enable(struct clk * c,int enable)395989ce049SDarwin Rambo static int ref_clk_enable(struct clk *c, int enable)
396989ce049SDarwin Rambo {
397989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
398989ce049SDarwin Rambo return 0;
399989ce049SDarwin Rambo }
400989ce049SDarwin Rambo
401989ce049SDarwin Rambo /* Reference clock operations */
402989ce049SDarwin Rambo struct clk_ops ref_clk_ops = {
403989ce049SDarwin Rambo .enable = ref_clk_enable,
404989ce049SDarwin Rambo };
405989ce049SDarwin Rambo
406989ce049SDarwin Rambo /*
407989ce049SDarwin Rambo * clk.h implementation follows
408989ce049SDarwin Rambo */
409989ce049SDarwin Rambo
410989ce049SDarwin Rambo /* Initialize the clock framework */
clk_init(void)411989ce049SDarwin Rambo int clk_init(void)
412989ce049SDarwin Rambo {
413989ce049SDarwin Rambo debug("%s:\n", __func__);
414989ce049SDarwin Rambo return 0;
415989ce049SDarwin Rambo }
416989ce049SDarwin Rambo
417989ce049SDarwin Rambo /* Get a clock handle, give a name string */
clk_get(const char * con_id)418989ce049SDarwin Rambo struct clk *clk_get(const char *con_id)
419989ce049SDarwin Rambo {
420989ce049SDarwin Rambo int i;
421989ce049SDarwin Rambo struct clk_lookup *clk_tblp;
422989ce049SDarwin Rambo
423989ce049SDarwin Rambo debug("%s: %s\n", __func__, con_id);
424989ce049SDarwin Rambo
425989ce049SDarwin Rambo clk_tblp = arch_clk_tbl;
426989ce049SDarwin Rambo for (i = 0; i < arch_clk_tbl_array_size; i++, clk_tblp++) {
427989ce049SDarwin Rambo if (clk_tblp->con_id) {
428989ce049SDarwin Rambo if (!con_id || strcmp(clk_tblp->con_id, con_id))
429989ce049SDarwin Rambo continue;
430989ce049SDarwin Rambo return clk_tblp->clk;
431989ce049SDarwin Rambo }
432989ce049SDarwin Rambo }
433989ce049SDarwin Rambo return NULL;
434989ce049SDarwin Rambo }
435989ce049SDarwin Rambo
436989ce049SDarwin Rambo /* Enable a clock */
clk_enable(struct clk * c)437989ce049SDarwin Rambo int clk_enable(struct clk *c)
438989ce049SDarwin Rambo {
439989ce049SDarwin Rambo int ret = 0;
440989ce049SDarwin Rambo
441989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
442989ce049SDarwin Rambo if (!c->ops || !c->ops->enable)
443989ce049SDarwin Rambo return -1;
444989ce049SDarwin Rambo
445989ce049SDarwin Rambo /* enable parent clock first */
446989ce049SDarwin Rambo if (c->parent)
447989ce049SDarwin Rambo ret = clk_enable(c->parent);
448989ce049SDarwin Rambo
449989ce049SDarwin Rambo if (ret)
450989ce049SDarwin Rambo return ret;
451989ce049SDarwin Rambo
452989ce049SDarwin Rambo if (!c->use_cnt) {
453989ce049SDarwin Rambo c->use_cnt++;
454989ce049SDarwin Rambo ret = c->ops->enable(c, 1);
455989ce049SDarwin Rambo }
456989ce049SDarwin Rambo
457989ce049SDarwin Rambo return ret;
458989ce049SDarwin Rambo }
459989ce049SDarwin Rambo
460989ce049SDarwin Rambo /* Disable a clock */
clk_disable(struct clk * c)461989ce049SDarwin Rambo void clk_disable(struct clk *c)
462989ce049SDarwin Rambo {
463989ce049SDarwin Rambo debug("%s: %s\n", __func__, c->name);
464989ce049SDarwin Rambo if (!c->ops || !c->ops->enable)
465989ce049SDarwin Rambo return;
466989ce049SDarwin Rambo
467989ce049SDarwin Rambo if (c->use_cnt) {
468989ce049SDarwin Rambo c->use_cnt--;
469989ce049SDarwin Rambo c->ops->enable(c, 0);
470989ce049SDarwin Rambo }
471989ce049SDarwin Rambo
472989ce049SDarwin Rambo /* disable parent */
473989ce049SDarwin Rambo if (c->parent)
474989ce049SDarwin Rambo clk_disable(c->parent);
475989ce049SDarwin Rambo }
476989ce049SDarwin Rambo
477989ce049SDarwin Rambo /* Get the clock rate */
clk_get_rate(struct clk * c)478989ce049SDarwin Rambo unsigned long clk_get_rate(struct clk *c)
479989ce049SDarwin Rambo {
480989ce049SDarwin Rambo unsigned long rate;
481989ce049SDarwin Rambo
482989ce049SDarwin Rambo if (!c || !c->ops || !c->ops->get_rate)
483989ce049SDarwin Rambo return 0;
484*6def7de3Sxypron.glpk@gmx.de debug("%s: %s\n", __func__, c->name);
485989ce049SDarwin Rambo
486989ce049SDarwin Rambo rate = c->ops->get_rate(c);
487989ce049SDarwin Rambo debug("%s: rate = %ld\n", __func__, rate);
488989ce049SDarwin Rambo return rate;
489989ce049SDarwin Rambo }
490989ce049SDarwin Rambo
491989ce049SDarwin Rambo /* Set the clock rate */
clk_set_rate(struct clk * c,unsigned long rate)492989ce049SDarwin Rambo int clk_set_rate(struct clk *c, unsigned long rate)
493989ce049SDarwin Rambo {
494989ce049SDarwin Rambo int ret;
495989ce049SDarwin Rambo
496989ce049SDarwin Rambo if (!c || !c->ops || !c->ops->set_rate)
497989ce049SDarwin Rambo return -EINVAL;
498*6def7de3Sxypron.glpk@gmx.de debug("%s: %s rate=%ld\n", __func__, c->name, rate);
499989ce049SDarwin Rambo
500989ce049SDarwin Rambo if (c->use_cnt)
501989ce049SDarwin Rambo return -EINVAL;
502989ce049SDarwin Rambo
503989ce049SDarwin Rambo ret = c->ops->set_rate(c, rate);
504989ce049SDarwin Rambo
505989ce049SDarwin Rambo return ret;
506989ce049SDarwin Rambo }
507989ce049SDarwin Rambo
508989ce049SDarwin Rambo /* Not required for this arch */
509989ce049SDarwin Rambo /*
510989ce049SDarwin Rambo long clk_round_rate(struct clk *clk, unsigned long rate);
511989ce049SDarwin Rambo int clk_set_parent(struct clk *clk, struct clk *parent);
512989ce049SDarwin Rambo struct clk *clk_get_parent(struct clk *clk);
513989ce049SDarwin Rambo */
514