xref: /openbmc/qemu/hw/misc/omap_clk.c (revision 062cfce8d4c077800d252b84c65da8a2dd03fd6f)
1e28bee8eSPaolo Bonzini /*
2e28bee8eSPaolo Bonzini  * OMAP clocks.
3e28bee8eSPaolo Bonzini  *
4e28bee8eSPaolo Bonzini  * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5e28bee8eSPaolo Bonzini  *
6e28bee8eSPaolo Bonzini  * Clocks data comes in part from arch/arm/mach-omap1/clock.h in Linux.
7e28bee8eSPaolo Bonzini  *
8e28bee8eSPaolo Bonzini  * This program is free software; you can redistribute it and/or
9e28bee8eSPaolo Bonzini  * modify it under the terms of the GNU General Public License as
10e28bee8eSPaolo Bonzini  * published by the Free Software Foundation; either version 2 of
11e28bee8eSPaolo Bonzini  * the License, or (at your option) any later version.
12e28bee8eSPaolo Bonzini  *
13e28bee8eSPaolo Bonzini  * This program is distributed in the hope that it will be useful,
14e28bee8eSPaolo Bonzini  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15e28bee8eSPaolo Bonzini  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e28bee8eSPaolo Bonzini  * GNU General Public License for more details.
17e28bee8eSPaolo Bonzini  *
18e28bee8eSPaolo Bonzini  * You should have received a copy of the GNU General Public License along
19e28bee8eSPaolo Bonzini  * with this program; if not, see <http://www.gnu.org/licenses/>.
20e28bee8eSPaolo Bonzini  */
2164552b6bSMarkus Armbruster 
220d1c9782SPeter Maydell #include "qemu/osdep.h"
23e28bee8eSPaolo Bonzini #include "hw/hw.h"
2464552b6bSMarkus Armbruster #include "hw/irq.h"
25e28bee8eSPaolo Bonzini #include "hw/arm/omap.h"
26e28bee8eSPaolo Bonzini 
27e28bee8eSPaolo Bonzini struct clk {
28e28bee8eSPaolo Bonzini     const char *name;
29e28bee8eSPaolo Bonzini     const char *alias;
30e28bee8eSPaolo Bonzini     struct clk *parent;
31e28bee8eSPaolo Bonzini     struct clk *child1;
32e28bee8eSPaolo Bonzini     struct clk *sibling;
33e28bee8eSPaolo Bonzini #define ALWAYS_ENABLED		(1 << 0)
34e28bee8eSPaolo Bonzini #define CLOCK_IN_OMAP310	(1 << 10)
35e28bee8eSPaolo Bonzini #define CLOCK_IN_OMAP730	(1 << 11)
36e28bee8eSPaolo Bonzini #define CLOCK_IN_OMAP1510	(1 << 12)
37e28bee8eSPaolo Bonzini #define CLOCK_IN_OMAP16XX	(1 << 13)
38e28bee8eSPaolo Bonzini     uint32_t flags;
39e28bee8eSPaolo Bonzini     int id;
40e28bee8eSPaolo Bonzini 
41e28bee8eSPaolo Bonzini     int running;		/* Is currently ticking */
42e28bee8eSPaolo Bonzini     int enabled;		/* Is enabled, regardless of its input clk */
43e28bee8eSPaolo Bonzini     unsigned long rate;		/* Current rate (if .running) */
44e28bee8eSPaolo Bonzini     unsigned int divisor;	/* Rate relative to input (if .enabled) */
45e28bee8eSPaolo Bonzini     unsigned int multiplier;	/* Rate relative to input (if .enabled) */
46e28bee8eSPaolo Bonzini     qemu_irq users[16];		/* Who to notify on change */
47e28bee8eSPaolo Bonzini     int usecount;		/* Automatically idle when unused */
48e28bee8eSPaolo Bonzini };
49e28bee8eSPaolo Bonzini 
50e28bee8eSPaolo Bonzini static struct clk xtal_osc12m = {
51e28bee8eSPaolo Bonzini     .name	= "xtal_osc_12m",
52e28bee8eSPaolo Bonzini     .rate	= 12000000,
53e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
54e28bee8eSPaolo Bonzini };
55e28bee8eSPaolo Bonzini 
56e28bee8eSPaolo Bonzini static struct clk xtal_osc32k = {
57e28bee8eSPaolo Bonzini     .name	= "xtal_osc_32k",
58e28bee8eSPaolo Bonzini     .rate	= 32768,
59*1e932548SPeter Maydell     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
60e28bee8eSPaolo Bonzini };
61e28bee8eSPaolo Bonzini 
62e28bee8eSPaolo Bonzini static struct clk ck_ref = {
63e28bee8eSPaolo Bonzini     .name	= "ck_ref",
64e28bee8eSPaolo Bonzini     .alias	= "clkin",
65e28bee8eSPaolo Bonzini     .parent	= &xtal_osc12m,
66e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
67e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
68e28bee8eSPaolo Bonzini };
69e28bee8eSPaolo Bonzini 
70e28bee8eSPaolo Bonzini /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
71e28bee8eSPaolo Bonzini static struct clk dpll1 = {
72e28bee8eSPaolo Bonzini     .name	= "dpll1",
73e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
74e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
75e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
76e28bee8eSPaolo Bonzini };
77e28bee8eSPaolo Bonzini 
78e28bee8eSPaolo Bonzini static struct clk dpll2 = {
79e28bee8eSPaolo Bonzini     .name	= "dpll2",
80e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
81e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
82e28bee8eSPaolo Bonzini };
83e28bee8eSPaolo Bonzini 
84e28bee8eSPaolo Bonzini static struct clk dpll3 = {
85e28bee8eSPaolo Bonzini     .name	= "dpll3",
86e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
87e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
88e28bee8eSPaolo Bonzini };
89e28bee8eSPaolo Bonzini 
90e28bee8eSPaolo Bonzini static struct clk dpll4 = {
91e28bee8eSPaolo Bonzini     .name	= "dpll4",
92e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
93e28bee8eSPaolo Bonzini     .multiplier	= 4,
94e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
95e28bee8eSPaolo Bonzini };
96e28bee8eSPaolo Bonzini 
97e28bee8eSPaolo Bonzini static struct clk apll = {
98e28bee8eSPaolo Bonzini     .name	= "apll",
99e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
100e28bee8eSPaolo Bonzini     .multiplier	= 48,
101e28bee8eSPaolo Bonzini     .divisor	= 12,
102e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
103e28bee8eSPaolo Bonzini };
104e28bee8eSPaolo Bonzini 
105e28bee8eSPaolo Bonzini static struct clk ck_48m = {
106e28bee8eSPaolo Bonzini     .name	= "ck_48m",
107e28bee8eSPaolo Bonzini     .parent	= &dpll4,	/* either dpll4 or apll */
108e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
109e28bee8eSPaolo Bonzini };
110e28bee8eSPaolo Bonzini 
111e28bee8eSPaolo Bonzini static struct clk ck_dpll1out = {
112e28bee8eSPaolo Bonzini     .name	= "ck_dpll1out",
113e28bee8eSPaolo Bonzini     .parent	= &dpll1,
114e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
115e28bee8eSPaolo Bonzini };
116e28bee8eSPaolo Bonzini 
117e28bee8eSPaolo Bonzini static struct clk sossi_ck = {
118e28bee8eSPaolo Bonzini     .name	= "ck_sossi",
119e28bee8eSPaolo Bonzini     .parent	= &ck_dpll1out,
120e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
121e28bee8eSPaolo Bonzini };
122e28bee8eSPaolo Bonzini 
123e28bee8eSPaolo Bonzini static struct clk clkm1 = {
124e28bee8eSPaolo Bonzini     .name	= "clkm1",
125e28bee8eSPaolo Bonzini     .alias	= "ck_gen1",
126e28bee8eSPaolo Bonzini     .parent	= &dpll1,
127e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
128e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
129e28bee8eSPaolo Bonzini };
130e28bee8eSPaolo Bonzini 
131e28bee8eSPaolo Bonzini static struct clk clkm2 = {
132e28bee8eSPaolo Bonzini     .name	= "clkm2",
133e28bee8eSPaolo Bonzini     .alias	= "ck_gen2",
134e28bee8eSPaolo Bonzini     .parent	= &dpll1,
135e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
136e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
137e28bee8eSPaolo Bonzini };
138e28bee8eSPaolo Bonzini 
139e28bee8eSPaolo Bonzini static struct clk clkm3 = {
140e28bee8eSPaolo Bonzini     .name	= "clkm3",
141e28bee8eSPaolo Bonzini     .alias	= "ck_gen3",
142e28bee8eSPaolo Bonzini     .parent	= &dpll1,	/* either dpll1 or ck_ref */
143e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
144e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
145e28bee8eSPaolo Bonzini };
146e28bee8eSPaolo Bonzini 
147e28bee8eSPaolo Bonzini static struct clk arm_ck = {
148e28bee8eSPaolo Bonzini     .name	= "arm_ck",
149e28bee8eSPaolo Bonzini     .alias	= "mpu_ck",
150e28bee8eSPaolo Bonzini     .parent	= &clkm1,
151e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
152e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
153e28bee8eSPaolo Bonzini };
154e28bee8eSPaolo Bonzini 
155e28bee8eSPaolo Bonzini static struct clk armper_ck = {
156e28bee8eSPaolo Bonzini     .name	= "armper_ck",
157e28bee8eSPaolo Bonzini     .alias	= "mpuper_ck",
158e28bee8eSPaolo Bonzini     .parent	= &clkm1,
159e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
160e28bee8eSPaolo Bonzini };
161e28bee8eSPaolo Bonzini 
162e28bee8eSPaolo Bonzini static struct clk arm_gpio_ck = {
163e28bee8eSPaolo Bonzini     .name	= "arm_gpio_ck",
164e28bee8eSPaolo Bonzini     .alias	= "mpu_gpio_ck",
165e28bee8eSPaolo Bonzini     .parent	= &clkm1,
166e28bee8eSPaolo Bonzini     .divisor	= 1,
167e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
168e28bee8eSPaolo Bonzini };
169e28bee8eSPaolo Bonzini 
170e28bee8eSPaolo Bonzini static struct clk armxor_ck = {
171e28bee8eSPaolo Bonzini     .name	= "armxor_ck",
172e28bee8eSPaolo Bonzini     .alias	= "mpuxor_ck",
173e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
174e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
175e28bee8eSPaolo Bonzini };
176e28bee8eSPaolo Bonzini 
177e28bee8eSPaolo Bonzini static struct clk armtim_ck = {
178e28bee8eSPaolo Bonzini     .name	= "armtim_ck",
179e28bee8eSPaolo Bonzini     .alias	= "mputim_ck",
180e28bee8eSPaolo Bonzini     .parent	= &ck_ref,	/* either CLKIN or DPLL1 */
181e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
182e28bee8eSPaolo Bonzini };
183e28bee8eSPaolo Bonzini 
184e28bee8eSPaolo Bonzini static struct clk armwdt_ck = {
185e28bee8eSPaolo Bonzini     .name	= "armwdt_ck",
186e28bee8eSPaolo Bonzini     .alias	= "mpuwd_ck",
187e28bee8eSPaolo Bonzini     .parent	= &clkm1,
188e28bee8eSPaolo Bonzini     .divisor	= 14,
189e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
190e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
191e28bee8eSPaolo Bonzini };
192e28bee8eSPaolo Bonzini 
193e28bee8eSPaolo Bonzini static struct clk arminth_ck16xx = {
194e28bee8eSPaolo Bonzini     .name	= "arminth_ck",
195e28bee8eSPaolo Bonzini     .parent	= &arm_ck,
196e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
197e28bee8eSPaolo Bonzini     /* Note: On 16xx the frequency can be divided by 2 by programming
198e28bee8eSPaolo Bonzini      * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
199e28bee8eSPaolo Bonzini      *
200e28bee8eSPaolo Bonzini      * 1510 version is in TC clocks.
201e28bee8eSPaolo Bonzini      */
202e28bee8eSPaolo Bonzini };
203e28bee8eSPaolo Bonzini 
204e28bee8eSPaolo Bonzini static struct clk dsp_ck = {
205e28bee8eSPaolo Bonzini     .name	= "dsp_ck",
206e28bee8eSPaolo Bonzini     .parent	= &clkm2,
207e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
208e28bee8eSPaolo Bonzini };
209e28bee8eSPaolo Bonzini 
210e28bee8eSPaolo Bonzini static struct clk dspmmu_ck = {
211e28bee8eSPaolo Bonzini     .name	= "dspmmu_ck",
212e28bee8eSPaolo Bonzini     .parent	= &clkm2,
213e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
214e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
215e28bee8eSPaolo Bonzini };
216e28bee8eSPaolo Bonzini 
217e28bee8eSPaolo Bonzini static struct clk dspper_ck = {
218e28bee8eSPaolo Bonzini     .name	= "dspper_ck",
219e28bee8eSPaolo Bonzini     .parent	= &clkm2,
220e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
221e28bee8eSPaolo Bonzini };
222e28bee8eSPaolo Bonzini 
223e28bee8eSPaolo Bonzini static struct clk dspxor_ck = {
224e28bee8eSPaolo Bonzini     .name	= "dspxor_ck",
225e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
226e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
227e28bee8eSPaolo Bonzini };
228e28bee8eSPaolo Bonzini 
229e28bee8eSPaolo Bonzini static struct clk dsptim_ck = {
230e28bee8eSPaolo Bonzini     .name	= "dsptim_ck",
231e28bee8eSPaolo Bonzini     .parent	= &ck_ref,
232e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
233e28bee8eSPaolo Bonzini };
234e28bee8eSPaolo Bonzini 
235e28bee8eSPaolo Bonzini static struct clk tc_ck = {
236e28bee8eSPaolo Bonzini     .name	= "tc_ck",
237e28bee8eSPaolo Bonzini     .parent	= &clkm3,
238e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
239e28bee8eSPaolo Bonzini             CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
240e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
241e28bee8eSPaolo Bonzini };
242e28bee8eSPaolo Bonzini 
243e28bee8eSPaolo Bonzini static struct clk arminth_ck15xx = {
244e28bee8eSPaolo Bonzini     .name	= "arminth_ck",
245e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
246e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
247e28bee8eSPaolo Bonzini     /* Note: On 1510 the frequency follows TC_CK
248e28bee8eSPaolo Bonzini      *
249e28bee8eSPaolo Bonzini      * 16xx version is in MPU clocks.
250e28bee8eSPaolo Bonzini      */
251e28bee8eSPaolo Bonzini };
252e28bee8eSPaolo Bonzini 
253e28bee8eSPaolo Bonzini static struct clk tipb_ck = {
254e28bee8eSPaolo Bonzini     /* No-idle controlled by "tc_ck" */
255e28bee8eSPaolo Bonzini     .name	= "tipb_ck",
256e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
257e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
258e28bee8eSPaolo Bonzini };
259e28bee8eSPaolo Bonzini 
260e28bee8eSPaolo Bonzini static struct clk l3_ocpi_ck = {
261e28bee8eSPaolo Bonzini     /* No-idle controlled by "tc_ck" */
262e28bee8eSPaolo Bonzini     .name	= "l3_ocpi_ck",
263e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
264e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
265e28bee8eSPaolo Bonzini };
266e28bee8eSPaolo Bonzini 
267e28bee8eSPaolo Bonzini static struct clk tc1_ck = {
268e28bee8eSPaolo Bonzini     .name	= "tc1_ck",
269e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
270e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
271e28bee8eSPaolo Bonzini };
272e28bee8eSPaolo Bonzini 
273e28bee8eSPaolo Bonzini static struct clk tc2_ck = {
274e28bee8eSPaolo Bonzini     .name	= "tc2_ck",
275e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
276e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
277e28bee8eSPaolo Bonzini };
278e28bee8eSPaolo Bonzini 
279e28bee8eSPaolo Bonzini static struct clk dma_ck = {
280e28bee8eSPaolo Bonzini     /* No-idle controlled by "tc_ck" */
281e28bee8eSPaolo Bonzini     .name	= "dma_ck",
282e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
283e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
284e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
285e28bee8eSPaolo Bonzini };
286e28bee8eSPaolo Bonzini 
287e28bee8eSPaolo Bonzini static struct clk dma_lcdfree_ck = {
288e28bee8eSPaolo Bonzini     .name	= "dma_lcdfree_ck",
289e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
290e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
291e28bee8eSPaolo Bonzini };
292e28bee8eSPaolo Bonzini 
293e28bee8eSPaolo Bonzini static struct clk api_ck = {
294e28bee8eSPaolo Bonzini     .name	= "api_ck",
295e28bee8eSPaolo Bonzini     .alias	= "mpui_ck",
296e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
297e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
298e28bee8eSPaolo Bonzini };
299e28bee8eSPaolo Bonzini 
300e28bee8eSPaolo Bonzini static struct clk lb_ck = {
301e28bee8eSPaolo Bonzini     .name	= "lb_ck",
302e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
303e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
304e28bee8eSPaolo Bonzini };
305e28bee8eSPaolo Bonzini 
306e28bee8eSPaolo Bonzini static struct clk lbfree_ck = {
307e28bee8eSPaolo Bonzini     .name	= "lbfree_ck",
308e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
309e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
310e28bee8eSPaolo Bonzini };
311e28bee8eSPaolo Bonzini 
312e28bee8eSPaolo Bonzini static struct clk hsab_ck = {
313e28bee8eSPaolo Bonzini     .name	= "hsab_ck",
314e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
315e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
316e28bee8eSPaolo Bonzini };
317e28bee8eSPaolo Bonzini 
318e28bee8eSPaolo Bonzini static struct clk rhea1_ck = {
319e28bee8eSPaolo Bonzini     .name	= "rhea1_ck",
320e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
321e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
322e28bee8eSPaolo Bonzini };
323e28bee8eSPaolo Bonzini 
324e28bee8eSPaolo Bonzini static struct clk rhea2_ck = {
325e28bee8eSPaolo Bonzini     .name	= "rhea2_ck",
326e28bee8eSPaolo Bonzini     .parent	= &tc_ck,
327e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
328e28bee8eSPaolo Bonzini };
329e28bee8eSPaolo Bonzini 
330e28bee8eSPaolo Bonzini static struct clk lcd_ck_16xx = {
331e28bee8eSPaolo Bonzini     .name	= "lcd_ck",
332e28bee8eSPaolo Bonzini     .parent	= &clkm3,
333e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
334e28bee8eSPaolo Bonzini };
335e28bee8eSPaolo Bonzini 
336e28bee8eSPaolo Bonzini static struct clk lcd_ck_1510 = {
337e28bee8eSPaolo Bonzini     .name	= "lcd_ck",
338e28bee8eSPaolo Bonzini     .parent	= &clkm3,
339e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
340e28bee8eSPaolo Bonzini };
341e28bee8eSPaolo Bonzini 
342e28bee8eSPaolo Bonzini static struct clk uart1_1510 = {
343e28bee8eSPaolo Bonzini     .name	= "uart1_ck",
344e28bee8eSPaolo Bonzini     /* Direct from ULPD, no real parent */
345e28bee8eSPaolo Bonzini     .parent	= &armper_ck,	/* either armper_ck or dpll4 */
346e28bee8eSPaolo Bonzini     .rate	= 12000000,
347e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
348e28bee8eSPaolo Bonzini };
349e28bee8eSPaolo Bonzini 
350e28bee8eSPaolo Bonzini static struct clk uart1_16xx = {
351e28bee8eSPaolo Bonzini     .name	= "uart1_ck",
352e28bee8eSPaolo Bonzini     /* Direct from ULPD, no real parent */
353e28bee8eSPaolo Bonzini     .parent	= &armper_ck,
354e28bee8eSPaolo Bonzini     .rate	= 48000000,
355e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
356e28bee8eSPaolo Bonzini };
357e28bee8eSPaolo Bonzini 
358e28bee8eSPaolo Bonzini static struct clk uart2_ck = {
359e28bee8eSPaolo Bonzini     .name	= "uart2_ck",
360e28bee8eSPaolo Bonzini     /* Direct from ULPD, no real parent */
361e28bee8eSPaolo Bonzini     .parent	= &armper_ck,	/* either armper_ck or dpll4 */
362e28bee8eSPaolo Bonzini     .rate	= 12000000,
363e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
364e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
365e28bee8eSPaolo Bonzini };
366e28bee8eSPaolo Bonzini 
367e28bee8eSPaolo Bonzini static struct clk uart3_1510 = {
368e28bee8eSPaolo Bonzini     .name	= "uart3_ck",
369e28bee8eSPaolo Bonzini     /* Direct from ULPD, no real parent */
370e28bee8eSPaolo Bonzini     .parent	= &armper_ck,	/* either armper_ck or dpll4 */
371e28bee8eSPaolo Bonzini     .rate	= 12000000,
372e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
373e28bee8eSPaolo Bonzini };
374e28bee8eSPaolo Bonzini 
375e28bee8eSPaolo Bonzini static struct clk uart3_16xx = {
376e28bee8eSPaolo Bonzini     .name	= "uart3_ck",
377e28bee8eSPaolo Bonzini     /* Direct from ULPD, no real parent */
378e28bee8eSPaolo Bonzini     .parent	= &armper_ck,
379e28bee8eSPaolo Bonzini     .rate	= 48000000,
380e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
381e28bee8eSPaolo Bonzini };
382e28bee8eSPaolo Bonzini 
383e28bee8eSPaolo Bonzini static struct clk usb_clk0 = {	/* 6 MHz output on W4_USB_CLK0 */
384e28bee8eSPaolo Bonzini     .name	= "usb_clk0",
385e28bee8eSPaolo Bonzini     .alias	= "usb.clko",
386e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent */
387e28bee8eSPaolo Bonzini     .rate	= 6000000,
388e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
389e28bee8eSPaolo Bonzini };
390e28bee8eSPaolo Bonzini 
391e28bee8eSPaolo Bonzini static struct clk usb_hhc_ck1510 = {
392e28bee8eSPaolo Bonzini     .name	= "usb_hhc_ck",
393e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent */
394e28bee8eSPaolo Bonzini     .rate	= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
395e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
396e28bee8eSPaolo Bonzini };
397e28bee8eSPaolo Bonzini 
398e28bee8eSPaolo Bonzini static struct clk usb_hhc_ck16xx = {
399e28bee8eSPaolo Bonzini     .name	= "usb_hhc_ck",
400e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent */
401e28bee8eSPaolo Bonzini     .rate	= 48000000,
402e28bee8eSPaolo Bonzini     /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
403e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
404e28bee8eSPaolo Bonzini };
405e28bee8eSPaolo Bonzini 
406e28bee8eSPaolo Bonzini static struct clk usb_w2fc_mclk = {
407e28bee8eSPaolo Bonzini     .name	= "usb_w2fc_mclk",
408e28bee8eSPaolo Bonzini     .alias	= "usb_w2fc_ck",
409e28bee8eSPaolo Bonzini     .parent	= &ck_48m,
410e28bee8eSPaolo Bonzini     .rate	= 48000000,
411e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
412e28bee8eSPaolo Bonzini };
413e28bee8eSPaolo Bonzini 
414e28bee8eSPaolo Bonzini static struct clk mclk_1510 = {
415e28bee8eSPaolo Bonzini     .name	= "mclk",
416e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
417e28bee8eSPaolo Bonzini     .rate	= 12000000,
418e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510,
419e28bee8eSPaolo Bonzini };
420e28bee8eSPaolo Bonzini 
421e28bee8eSPaolo Bonzini static struct clk bclk_310 = {
422e28bee8eSPaolo Bonzini     .name	= "bt_mclk_out",	/* Alias midi_mclk_out? */
423e28bee8eSPaolo Bonzini     .parent	= &armper_ck,
424e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310,
425e28bee8eSPaolo Bonzini };
426e28bee8eSPaolo Bonzini 
427e28bee8eSPaolo Bonzini static struct clk mclk_310 = {
428e28bee8eSPaolo Bonzini     .name	= "com_mclk_out",
429e28bee8eSPaolo Bonzini     .parent	= &armper_ck,
430e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310,
431e28bee8eSPaolo Bonzini };
432e28bee8eSPaolo Bonzini 
433e28bee8eSPaolo Bonzini static struct clk mclk_16xx = {
434e28bee8eSPaolo Bonzini     .name	= "mclk",
435e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
436e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
437e28bee8eSPaolo Bonzini };
438e28bee8eSPaolo Bonzini 
439e28bee8eSPaolo Bonzini static struct clk bclk_1510 = {
440e28bee8eSPaolo Bonzini     .name	= "bclk",
441e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
442e28bee8eSPaolo Bonzini     .rate	= 12000000,
443e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510,
444e28bee8eSPaolo Bonzini };
445e28bee8eSPaolo Bonzini 
446e28bee8eSPaolo Bonzini static struct clk bclk_16xx = {
447e28bee8eSPaolo Bonzini     .name	= "bclk",
448e28bee8eSPaolo Bonzini     /* Direct from ULPD, no parent. May be enabled by ext hardware. */
449e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
450e28bee8eSPaolo Bonzini };
451e28bee8eSPaolo Bonzini 
452e28bee8eSPaolo Bonzini static struct clk mmc1_ck = {
453e28bee8eSPaolo Bonzini     .name	= "mmc_ck",
454e28bee8eSPaolo Bonzini     .id		= 1,
455e28bee8eSPaolo Bonzini     /* Functional clock is direct from ULPD, interface clock is ARMPER */
456e28bee8eSPaolo Bonzini     .parent	= &armper_ck,	/* either armper_ck or dpll4 */
457e28bee8eSPaolo Bonzini     .rate	= 48000000,
458e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
459e28bee8eSPaolo Bonzini };
460e28bee8eSPaolo Bonzini 
461e28bee8eSPaolo Bonzini static struct clk mmc2_ck = {
462e28bee8eSPaolo Bonzini     .name	= "mmc_ck",
463e28bee8eSPaolo Bonzini     .id		= 2,
464e28bee8eSPaolo Bonzini     /* Functional clock is direct from ULPD, interface clock is ARMPER */
465e28bee8eSPaolo Bonzini     .parent	= &armper_ck,
466e28bee8eSPaolo Bonzini     .rate	= 48000000,
467e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX,
468e28bee8eSPaolo Bonzini };
469e28bee8eSPaolo Bonzini 
470e28bee8eSPaolo Bonzini static struct clk cam_mclk = {
471e28bee8eSPaolo Bonzini     .name	= "cam.mclk",
472e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
473e28bee8eSPaolo Bonzini     .rate	= 12000000,
474e28bee8eSPaolo Bonzini };
475e28bee8eSPaolo Bonzini 
476e28bee8eSPaolo Bonzini static struct clk cam_exclk = {
477e28bee8eSPaolo Bonzini     .name	= "cam.exclk",
478e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
479e28bee8eSPaolo Bonzini     /* Either 12M from cam.mclk or 48M from dpll4 */
480e28bee8eSPaolo Bonzini     .parent	= &cam_mclk,
481e28bee8eSPaolo Bonzini };
482e28bee8eSPaolo Bonzini 
483e28bee8eSPaolo Bonzini static struct clk cam_lclk = {
484e28bee8eSPaolo Bonzini     .name	= "cam.lclk",
485e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
486e28bee8eSPaolo Bonzini };
487e28bee8eSPaolo Bonzini 
488e28bee8eSPaolo Bonzini static struct clk i2c_fck = {
489e28bee8eSPaolo Bonzini     .name	= "i2c_fck",
490e28bee8eSPaolo Bonzini     .id		= 1,
491e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
492e28bee8eSPaolo Bonzini             ALWAYS_ENABLED,
493e28bee8eSPaolo Bonzini     .parent	= &armxor_ck,
494e28bee8eSPaolo Bonzini };
495e28bee8eSPaolo Bonzini 
496e28bee8eSPaolo Bonzini static struct clk i2c_ick = {
497e28bee8eSPaolo Bonzini     .name	= "i2c_ick",
498e28bee8eSPaolo Bonzini     .id		= 1,
499e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
500e28bee8eSPaolo Bonzini     .parent	= &armper_ck,
501e28bee8eSPaolo Bonzini };
502e28bee8eSPaolo Bonzini 
503e28bee8eSPaolo Bonzini static struct clk clk32k = {
504e28bee8eSPaolo Bonzini     .name	= "clk32-kHz",
505e28bee8eSPaolo Bonzini     .flags	= CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
506*1e932548SPeter Maydell             ALWAYS_ENABLED,
507e28bee8eSPaolo Bonzini     .parent	= &xtal_osc32k,
508e28bee8eSPaolo Bonzini };
509e28bee8eSPaolo Bonzini 
510e28bee8eSPaolo Bonzini static struct clk *onchip_clks[] = {
511e28bee8eSPaolo Bonzini     /* OMAP 1 */
512e28bee8eSPaolo Bonzini 
513e28bee8eSPaolo Bonzini     /* non-ULPD clocks */
514e28bee8eSPaolo Bonzini     &xtal_osc12m,
515e28bee8eSPaolo Bonzini     &xtal_osc32k,
516e28bee8eSPaolo Bonzini     &ck_ref,
517e28bee8eSPaolo Bonzini     &dpll1,
518e28bee8eSPaolo Bonzini     &dpll2,
519e28bee8eSPaolo Bonzini     &dpll3,
520e28bee8eSPaolo Bonzini     &dpll4,
521e28bee8eSPaolo Bonzini     &apll,
522e28bee8eSPaolo Bonzini     &ck_48m,
523e28bee8eSPaolo Bonzini     /* CK_GEN1 clocks */
524e28bee8eSPaolo Bonzini     &clkm1,
525e28bee8eSPaolo Bonzini     &ck_dpll1out,
526e28bee8eSPaolo Bonzini     &sossi_ck,
527e28bee8eSPaolo Bonzini     &arm_ck,
528e28bee8eSPaolo Bonzini     &armper_ck,
529e28bee8eSPaolo Bonzini     &arm_gpio_ck,
530e28bee8eSPaolo Bonzini     &armxor_ck,
531e28bee8eSPaolo Bonzini     &armtim_ck,
532e28bee8eSPaolo Bonzini     &armwdt_ck,
533e28bee8eSPaolo Bonzini     &arminth_ck15xx,  &arminth_ck16xx,
534e28bee8eSPaolo Bonzini     /* CK_GEN2 clocks */
535e28bee8eSPaolo Bonzini     &clkm2,
536e28bee8eSPaolo Bonzini     &dsp_ck,
537e28bee8eSPaolo Bonzini     &dspmmu_ck,
538e28bee8eSPaolo Bonzini     &dspper_ck,
539e28bee8eSPaolo Bonzini     &dspxor_ck,
540e28bee8eSPaolo Bonzini     &dsptim_ck,
541e28bee8eSPaolo Bonzini     /* CK_GEN3 clocks */
542e28bee8eSPaolo Bonzini     &clkm3,
543e28bee8eSPaolo Bonzini     &tc_ck,
544e28bee8eSPaolo Bonzini     &tipb_ck,
545e28bee8eSPaolo Bonzini     &l3_ocpi_ck,
546e28bee8eSPaolo Bonzini     &tc1_ck,
547e28bee8eSPaolo Bonzini     &tc2_ck,
548e28bee8eSPaolo Bonzini     &dma_ck,
549e28bee8eSPaolo Bonzini     &dma_lcdfree_ck,
550e28bee8eSPaolo Bonzini     &api_ck,
551e28bee8eSPaolo Bonzini     &lb_ck,
552e28bee8eSPaolo Bonzini     &lbfree_ck,
553e28bee8eSPaolo Bonzini     &hsab_ck,
554e28bee8eSPaolo Bonzini     &rhea1_ck,
555e28bee8eSPaolo Bonzini     &rhea2_ck,
556e28bee8eSPaolo Bonzini     &lcd_ck_16xx,
557e28bee8eSPaolo Bonzini     &lcd_ck_1510,
558e28bee8eSPaolo Bonzini     /* ULPD clocks */
559e28bee8eSPaolo Bonzini     &uart1_1510,
560e28bee8eSPaolo Bonzini     &uart1_16xx,
561e28bee8eSPaolo Bonzini     &uart2_ck,
562e28bee8eSPaolo Bonzini     &uart3_1510,
563e28bee8eSPaolo Bonzini     &uart3_16xx,
564e28bee8eSPaolo Bonzini     &usb_clk0,
565e28bee8eSPaolo Bonzini     &usb_hhc_ck1510, &usb_hhc_ck16xx,
566e28bee8eSPaolo Bonzini     &mclk_1510,  &mclk_16xx, &mclk_310,
567e28bee8eSPaolo Bonzini     &bclk_1510,  &bclk_16xx, &bclk_310,
568e28bee8eSPaolo Bonzini     &mmc1_ck,
569e28bee8eSPaolo Bonzini     &mmc2_ck,
570e28bee8eSPaolo Bonzini     &cam_mclk,
571e28bee8eSPaolo Bonzini     &cam_exclk,
572e28bee8eSPaolo Bonzini     &cam_lclk,
573e28bee8eSPaolo Bonzini     &clk32k,
574e28bee8eSPaolo Bonzini     &usb_w2fc_mclk,
575e28bee8eSPaolo Bonzini     /* Virtual clocks */
576e28bee8eSPaolo Bonzini     &i2c_fck,
577e28bee8eSPaolo Bonzini     &i2c_ick,
578e28bee8eSPaolo Bonzini 
579e28bee8eSPaolo Bonzini     NULL
580e28bee8eSPaolo Bonzini };
581e28bee8eSPaolo Bonzini 
omap_clk_adduser(struct clk * clk,qemu_irq user)582e28bee8eSPaolo Bonzini void omap_clk_adduser(struct clk *clk, qemu_irq user)
583e28bee8eSPaolo Bonzini {
584e28bee8eSPaolo Bonzini     qemu_irq *i;
585e28bee8eSPaolo Bonzini 
586e28bee8eSPaolo Bonzini     for (i = clk->users; *i; i ++);
587e28bee8eSPaolo Bonzini     *i = user;
588e28bee8eSPaolo Bonzini }
589e28bee8eSPaolo Bonzini 
omap_findclk(struct omap_mpu_state_s * mpu,const char * name)590e28bee8eSPaolo Bonzini struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
591e28bee8eSPaolo Bonzini {
592e28bee8eSPaolo Bonzini     struct clk *i;
593e28bee8eSPaolo Bonzini 
594e28bee8eSPaolo Bonzini     for (i = mpu->clks; i->name; i ++)
595e28bee8eSPaolo Bonzini         if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
596e28bee8eSPaolo Bonzini             return i;
597a89f364aSAlistair Francis     hw_error("%s: %s not found\n", __func__, name);
598e28bee8eSPaolo Bonzini }
599e28bee8eSPaolo Bonzini 
omap_clk_get(struct clk * clk)600e28bee8eSPaolo Bonzini void omap_clk_get(struct clk *clk)
601e28bee8eSPaolo Bonzini {
602e28bee8eSPaolo Bonzini     clk->usecount ++;
603e28bee8eSPaolo Bonzini }
604e28bee8eSPaolo Bonzini 
omap_clk_put(struct clk * clk)605e28bee8eSPaolo Bonzini void omap_clk_put(struct clk *clk)
606e28bee8eSPaolo Bonzini {
607e28bee8eSPaolo Bonzini     if (!(clk->usecount --))
608a89f364aSAlistair Francis         hw_error("%s: %s is not in use\n", __func__, clk->name);
609e28bee8eSPaolo Bonzini }
610e28bee8eSPaolo Bonzini 
omap_clk_update(struct clk * clk)611e28bee8eSPaolo Bonzini static void omap_clk_update(struct clk *clk)
612e28bee8eSPaolo Bonzini {
613e28bee8eSPaolo Bonzini     int parent, running;
614e28bee8eSPaolo Bonzini     qemu_irq *user;
615e28bee8eSPaolo Bonzini     struct clk *i;
616e28bee8eSPaolo Bonzini 
617e28bee8eSPaolo Bonzini     if (clk->parent)
618e28bee8eSPaolo Bonzini         parent = clk->parent->running;
619e28bee8eSPaolo Bonzini     else
620e28bee8eSPaolo Bonzini         parent = 1;
621e28bee8eSPaolo Bonzini 
622e28bee8eSPaolo Bonzini     running = parent && (clk->enabled ||
623e28bee8eSPaolo Bonzini                     ((clk->flags & ALWAYS_ENABLED) && clk->usecount));
624e28bee8eSPaolo Bonzini     if (clk->running != running) {
625e28bee8eSPaolo Bonzini         clk->running = running;
626e28bee8eSPaolo Bonzini         for (user = clk->users; *user; user ++)
627e28bee8eSPaolo Bonzini             qemu_set_irq(*user, running);
628e28bee8eSPaolo Bonzini         for (i = clk->child1; i; i = i->sibling)
629e28bee8eSPaolo Bonzini             omap_clk_update(i);
630e28bee8eSPaolo Bonzini     }
631e28bee8eSPaolo Bonzini }
632e28bee8eSPaolo Bonzini 
omap_clk_rate_update_full(struct clk * clk,unsigned long int rate,unsigned long int div,unsigned long int mult)633e28bee8eSPaolo Bonzini static void omap_clk_rate_update_full(struct clk *clk, unsigned long int rate,
634e28bee8eSPaolo Bonzini                 unsigned long int div, unsigned long int mult)
635e28bee8eSPaolo Bonzini {
636e28bee8eSPaolo Bonzini     struct clk *i;
637e28bee8eSPaolo Bonzini     qemu_irq *user;
638e28bee8eSPaolo Bonzini 
639e28bee8eSPaolo Bonzini     clk->rate = muldiv64(rate, mult, div);
640e28bee8eSPaolo Bonzini     if (clk->running)
641e28bee8eSPaolo Bonzini         for (user = clk->users; *user; user ++)
642e28bee8eSPaolo Bonzini             qemu_irq_raise(*user);
643e28bee8eSPaolo Bonzini     for (i = clk->child1; i; i = i->sibling)
644e28bee8eSPaolo Bonzini         omap_clk_rate_update_full(i, rate,
645e28bee8eSPaolo Bonzini                         div * i->divisor, mult * i->multiplier);
646e28bee8eSPaolo Bonzini }
647e28bee8eSPaolo Bonzini 
omap_clk_rate_update(struct clk * clk)648e28bee8eSPaolo Bonzini static void omap_clk_rate_update(struct clk *clk)
649e28bee8eSPaolo Bonzini {
650e28bee8eSPaolo Bonzini     struct clk *i;
651e28bee8eSPaolo Bonzini     unsigned long int div, mult = div = 1;
652e28bee8eSPaolo Bonzini 
653e28bee8eSPaolo Bonzini     for (i = clk; i->parent; i = i->parent) {
654e28bee8eSPaolo Bonzini         div *= i->divisor;
655e28bee8eSPaolo Bonzini         mult *= i->multiplier;
656e28bee8eSPaolo Bonzini     }
657e28bee8eSPaolo Bonzini 
658e28bee8eSPaolo Bonzini     omap_clk_rate_update_full(clk, i->rate, div, mult);
659e28bee8eSPaolo Bonzini }
660e28bee8eSPaolo Bonzini 
omap_clk_reparent(struct clk * clk,struct clk * parent)661e28bee8eSPaolo Bonzini void omap_clk_reparent(struct clk *clk, struct clk *parent)
662e28bee8eSPaolo Bonzini {
663e28bee8eSPaolo Bonzini     struct clk **p;
664e28bee8eSPaolo Bonzini 
665e28bee8eSPaolo Bonzini     if (clk->parent) {
666e28bee8eSPaolo Bonzini         for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling);
667e28bee8eSPaolo Bonzini         *p = clk->sibling;
668e28bee8eSPaolo Bonzini     }
669e28bee8eSPaolo Bonzini 
670e28bee8eSPaolo Bonzini     clk->parent = parent;
671e28bee8eSPaolo Bonzini     if (parent) {
672e28bee8eSPaolo Bonzini         clk->sibling = parent->child1;
673e28bee8eSPaolo Bonzini         parent->child1 = clk;
674e28bee8eSPaolo Bonzini         omap_clk_update(clk);
675e28bee8eSPaolo Bonzini         omap_clk_rate_update(clk);
676e28bee8eSPaolo Bonzini     } else
677e28bee8eSPaolo Bonzini         clk->sibling = NULL;
678e28bee8eSPaolo Bonzini }
679e28bee8eSPaolo Bonzini 
omap_clk_onoff(struct clk * clk,int on)680e28bee8eSPaolo Bonzini void omap_clk_onoff(struct clk *clk, int on)
681e28bee8eSPaolo Bonzini {
682e28bee8eSPaolo Bonzini     clk->enabled = on;
683e28bee8eSPaolo Bonzini     omap_clk_update(clk);
684e28bee8eSPaolo Bonzini }
685e28bee8eSPaolo Bonzini 
omap_clk_canidle(struct clk * clk,int can)686e28bee8eSPaolo Bonzini void omap_clk_canidle(struct clk *clk, int can)
687e28bee8eSPaolo Bonzini {
688e28bee8eSPaolo Bonzini     if (can)
689e28bee8eSPaolo Bonzini         omap_clk_put(clk);
690e28bee8eSPaolo Bonzini     else
691e28bee8eSPaolo Bonzini         omap_clk_get(clk);
692e28bee8eSPaolo Bonzini }
693e28bee8eSPaolo Bonzini 
omap_clk_setrate(struct clk * clk,int divide,int multiply)694e28bee8eSPaolo Bonzini void omap_clk_setrate(struct clk *clk, int divide, int multiply)
695e28bee8eSPaolo Bonzini {
696e28bee8eSPaolo Bonzini     clk->divisor = divide;
697e28bee8eSPaolo Bonzini     clk->multiplier = multiply;
698e28bee8eSPaolo Bonzini     omap_clk_rate_update(clk);
699e28bee8eSPaolo Bonzini }
700e28bee8eSPaolo Bonzini 
omap_clk_getrate(omap_clk clk)701e28bee8eSPaolo Bonzini int64_t omap_clk_getrate(omap_clk clk)
702e28bee8eSPaolo Bonzini {
703e28bee8eSPaolo Bonzini     return clk->rate;
704e28bee8eSPaolo Bonzini }
705e28bee8eSPaolo Bonzini 
omap_clk_init(struct omap_mpu_state_s * mpu)706e28bee8eSPaolo Bonzini void omap_clk_init(struct omap_mpu_state_s *mpu)
707e28bee8eSPaolo Bonzini {
708e28bee8eSPaolo Bonzini     struct clk **i, *j, *k;
709e28bee8eSPaolo Bonzini     int count;
710e28bee8eSPaolo Bonzini     int flag;
711e28bee8eSPaolo Bonzini 
712e28bee8eSPaolo Bonzini     if (cpu_is_omap310(mpu))
713e28bee8eSPaolo Bonzini         flag = CLOCK_IN_OMAP310;
714e28bee8eSPaolo Bonzini     else if (cpu_is_omap1510(mpu))
715e28bee8eSPaolo Bonzini         flag = CLOCK_IN_OMAP1510;
716e28bee8eSPaolo Bonzini     else
717e28bee8eSPaolo Bonzini         return;
718e28bee8eSPaolo Bonzini 
719e28bee8eSPaolo Bonzini     for (i = onchip_clks, count = 0; *i; i ++)
720e28bee8eSPaolo Bonzini         if ((*i)->flags & flag)
721e28bee8eSPaolo Bonzini             count ++;
722b45c03f5SMarkus Armbruster     mpu->clks = g_new0(struct clk, count + 1);
723e28bee8eSPaolo Bonzini     for (i = onchip_clks, j = mpu->clks; *i; i ++)
724e28bee8eSPaolo Bonzini         if ((*i)->flags & flag) {
725e28bee8eSPaolo Bonzini             memcpy(j, *i, sizeof(struct clk));
726e28bee8eSPaolo Bonzini             for (k = mpu->clks; k < j; k ++)
727e28bee8eSPaolo Bonzini                 if (j->parent && !strcmp(j->parent->name, k->name)) {
728e28bee8eSPaolo Bonzini                     j->parent = k;
729e28bee8eSPaolo Bonzini                     j->sibling = k->child1;
730e28bee8eSPaolo Bonzini                     k->child1 = j;
731e28bee8eSPaolo Bonzini                 } else if (k->parent && !strcmp(k->parent->name, j->name)) {
732e28bee8eSPaolo Bonzini                     k->parent = j;
733e28bee8eSPaolo Bonzini                     k->sibling = j->child1;
734e28bee8eSPaolo Bonzini                     j->child1 = k;
735e28bee8eSPaolo Bonzini                 }
736e28bee8eSPaolo Bonzini             j->divisor = j->divisor ?: 1;
737e28bee8eSPaolo Bonzini             j->multiplier = j->multiplier ?: 1;
738e28bee8eSPaolo Bonzini             j ++;
739e28bee8eSPaolo Bonzini         }
740e28bee8eSPaolo Bonzini     for (j = mpu->clks; count --; j ++) {
741e28bee8eSPaolo Bonzini         omap_clk_update(j);
742e28bee8eSPaolo Bonzini         omap_clk_rate_update(j);
743e28bee8eSPaolo Bonzini     }
744e28bee8eSPaolo Bonzini }
745