blob: 7dde6a82f514834ac76ed9a457f6ccc7a5176a03 [file] [log] [blame]
Binghua Duan02c981c2011-07-08 17:40:12 +08001/*
Barry Song7bf21bc2014-01-15 14:11:34 +08002 * common clks module for all SiRF SoCs
Binghua Duan02c981c2011-07-08 17:40:12 +08003 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
Binghua Duan02c981c2011-07-08 17:40:12 +08009#define KHZ 1000
10#define MHZ (KHZ * KHZ)
11
Barry Song7bf21bc2014-01-15 14:11:34 +080012static void *sirfsoc_clk_vbase;
13static void *sirfsoc_rsc_vbase;
14static struct clk_onecell_data clk_data;
15
Binghua Duan198678b2012-08-20 06:42:36 +000016/*
17 * SiRFprimaII clock controller
18 * - 2 oscillators: osc-26MHz, rtc-32.768KHz
19 * - 3 standard configurable plls: pll1, pll2 & pll3
20 * - 2 exclusive plls: usb phy pll and sata phy pll
21 * - 8 clock domains: cpu/cpudiv, mem/memdiv, sys/io, dsp, graphic, multimedia,
22 * display and sdphy.
23 * Each clock domain can select its own clock source from five clock sources,
24 * X_XIN, X_XINW, PLL1, PLL2 and PLL3. The domain clock is used as the source
25 * clock of the group clock.
26 * - dsp domain: gps, mf
27 * - io domain: dmac, nand, audio, uart, i2c, spi, usp, pwm, pulse
28 * - sys domain: security
29 */
30
31struct clk_pll {
32 struct clk_hw hw;
33 unsigned short regofs; /* register offset */
Binghua Duan02c981c2011-07-08 17:40:12 +080034};
35
Binghua Duan198678b2012-08-20 06:42:36 +000036#define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
37
38struct clk_dmn {
39 struct clk_hw hw;
Binghua Duan02c981c2011-07-08 17:40:12 +080040 signed char enable_bit; /* enable bit: 0 ~ 63 */
41 unsigned short regofs; /* register offset */
Binghua Duan02c981c2011-07-08 17:40:12 +080042};
43
Binghua Duan198678b2012-08-20 06:42:36 +000044#define to_dmnclk(_hw) container_of(_hw, struct clk_dmn, hw)
45
46struct clk_std {
47 struct clk_hw hw;
48 signed char enable_bit; /* enable bit: 0 ~ 63 */
49};
50
51#define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
52
53static int std_clk_is_enabled(struct clk_hw *hw);
54static int std_clk_enable(struct clk_hw *hw);
55static void std_clk_disable(struct clk_hw *hw);
Binghua Duan02c981c2011-07-08 17:40:12 +080056
57static inline unsigned long clkc_readl(unsigned reg)
58{
Binghua Duan198678b2012-08-20 06:42:36 +000059 return readl(sirfsoc_clk_vbase + reg);
Binghua Duan02c981c2011-07-08 17:40:12 +080060}
61
62static inline void clkc_writel(u32 val, unsigned reg)
63{
Binghua Duan198678b2012-08-20 06:42:36 +000064 writel(val, sirfsoc_clk_vbase + reg);
Binghua Duan02c981c2011-07-08 17:40:12 +080065}
66
67/*
Binghua Duan02c981c2011-07-08 17:40:12 +080068 * std pll
69 */
Binghua Duan198678b2012-08-20 06:42:36 +000070
71static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
72 unsigned long parent_rate)
Binghua Duan02c981c2011-07-08 17:40:12 +080073{
Binghua Duan198678b2012-08-20 06:42:36 +000074 unsigned long fin = parent_rate;
75 struct clk_pll *clk = to_pllclk(hw);
Binghua Duan02c981c2011-07-08 17:40:12 +080076 u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
77 SIRFSOC_CLKC_PLL1_CFG0;
78
79 if (clkc_readl(regcfg2) & BIT(2)) {
80 /* pll bypass mode */
Binghua Duan198678b2012-08-20 06:42:36 +000081 return fin;
Binghua Duan02c981c2011-07-08 17:40:12 +080082 } else {
83 /* fout = fin * nf / nr / od */
84 u32 cfg0 = clkc_readl(clk->regofs);
85 u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
86 u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
87 u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
88 WARN_ON(fin % MHZ);
Binghua Duan198678b2012-08-20 06:42:36 +000089 return fin / MHZ * nf / nr / od * MHZ;
Binghua Duan02c981c2011-07-08 17:40:12 +080090 }
Binghua Duan02c981c2011-07-08 17:40:12 +080091}
92
Binghua Duan198678b2012-08-20 06:42:36 +000093static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
94 unsigned long *parent_rate)
Binghua Duan02c981c2011-07-08 17:40:12 +080095{
Binghua Duan198678b2012-08-20 06:42:36 +000096 unsigned long fin, nf, nr, od;
Barry Song7bf21bc2014-01-15 14:11:34 +080097 u64 dividend;
Binghua Duan198678b2012-08-20 06:42:36 +000098
99 /*
100 * fout = fin * nf / (nr * od);
101 * set od = 1, nr = fin/MHz, so fout = nf * MHz
102 */
103 rate = rate - rate % MHZ;
104
105 nf = rate / MHZ;
106 if (nf > BIT(13))
107 nf = BIT(13);
108 if (nf < 1)
109 nf = 1;
110
111 fin = *parent_rate;
112
113 nr = fin / MHZ;
114 if (nr > BIT(6))
115 nr = BIT(6);
116 od = 1;
117
Barry Song7bf21bc2014-01-15 14:11:34 +0800118 dividend = (u64)fin * nf;
119 do_div(dividend, nr * od);
120
121 return (long)dividend;
Binghua Duan198678b2012-08-20 06:42:36 +0000122}
123
124static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
125 unsigned long parent_rate)
126{
127 struct clk_pll *clk = to_pllclk(hw);
Binghua Duan02c981c2011-07-08 17:40:12 +0800128 unsigned long fin, nf, nr, od, reg;
129
130 /*
131 * fout = fin * nf / (nr * od);
132 * set od = 1, nr = fin/MHz, so fout = nf * MHz
133 */
134
135 nf = rate / MHZ;
136 if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
137 return -EINVAL;
138
Binghua Duan198678b2012-08-20 06:42:36 +0000139 fin = parent_rate;
Binghua Duan02c981c2011-07-08 17:40:12 +0800140 BUG_ON(fin < MHZ);
141
142 nr = fin / MHZ;
143 BUG_ON((fin % MHZ) || nr > BIT(6));
144
145 od = 1;
146
147 reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
148 clkc_writel(reg, clk->regofs);
149
150 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
151 clkc_writel((nf >> 1) - 1, reg);
152
153 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
154 while (!(clkc_readl(reg) & BIT(6)))
155 cpu_relax();
156
Binghua Duan02c981c2011-07-08 17:40:12 +0800157 return 0;
158}
159
Barry Song7bf21bc2014-01-15 14:11:34 +0800160static long cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
161 unsigned long *parent_rate)
162{
163 /*
164 * SiRF SoC has not cpu clock control,
165 * So bypass to it's parent pll.
166 */
167 struct clk *parent_clk = clk_get_parent(hw->clk);
168 struct clk *pll_parent_clk = clk_get_parent(parent_clk);
169 unsigned long pll_parent_rate = clk_get_rate(pll_parent_clk);
170 return pll_clk_round_rate(__clk_get_hw(parent_clk), rate, &pll_parent_rate);
171}
172
173static unsigned long cpu_clk_recalc_rate(struct clk_hw *hw,
174 unsigned long parent_rate)
175{
176 /*
177 * SiRF SoC has not cpu clock control,
178 * So return the parent pll rate.
179 */
180 struct clk *parent_clk = clk_get_parent(hw->clk);
181 return __clk_get_rate(parent_clk);
182}
183
Binghua Duan02c981c2011-07-08 17:40:12 +0800184static struct clk_ops std_pll_ops = {
Binghua Duan198678b2012-08-20 06:42:36 +0000185 .recalc_rate = pll_clk_recalc_rate,
186 .round_rate = pll_clk_round_rate,
187 .set_rate = pll_clk_set_rate,
Binghua Duan02c981c2011-07-08 17:40:12 +0800188};
189
Binghua Duan198678b2012-08-20 06:42:36 +0000190static const char *pll_clk_parents[] = {
191 "osc",
192};
193
194static struct clk_init_data clk_pll1_init = {
195 .name = "pll1",
196 .ops = &std_pll_ops,
197 .parent_names = pll_clk_parents,
198 .num_parents = ARRAY_SIZE(pll_clk_parents),
199};
200
201static struct clk_init_data clk_pll2_init = {
202 .name = "pll2",
203 .ops = &std_pll_ops,
204 .parent_names = pll_clk_parents,
205 .num_parents = ARRAY_SIZE(pll_clk_parents),
206};
207
208static struct clk_init_data clk_pll3_init = {
209 .name = "pll3",
210 .ops = &std_pll_ops,
211 .parent_names = pll_clk_parents,
212 .num_parents = ARRAY_SIZE(pll_clk_parents),
213};
214
215static struct clk_pll clk_pll1 = {
Binghua Duan02c981c2011-07-08 17:40:12 +0800216 .regofs = SIRFSOC_CLKC_PLL1_CFG0,
Binghua Duan198678b2012-08-20 06:42:36 +0000217 .hw = {
218 .init = &clk_pll1_init,
219 },
Binghua Duan02c981c2011-07-08 17:40:12 +0800220};
221
Binghua Duan198678b2012-08-20 06:42:36 +0000222static struct clk_pll clk_pll2 = {
Binghua Duan02c981c2011-07-08 17:40:12 +0800223 .regofs = SIRFSOC_CLKC_PLL2_CFG0,
Binghua Duan198678b2012-08-20 06:42:36 +0000224 .hw = {
225 .init = &clk_pll2_init,
226 },
Binghua Duan02c981c2011-07-08 17:40:12 +0800227};
228
Binghua Duan198678b2012-08-20 06:42:36 +0000229static struct clk_pll clk_pll3 = {
Binghua Duan02c981c2011-07-08 17:40:12 +0800230 .regofs = SIRFSOC_CLKC_PLL3_CFG0,
Binghua Duan198678b2012-08-20 06:42:36 +0000231 .hw = {
232 .init = &clk_pll3_init,
233 },
Binghua Duan02c981c2011-07-08 17:40:12 +0800234};
235
236/*
Binghua Duan198678b2012-08-20 06:42:36 +0000237 * usb uses specified pll
Binghua Duan02c981c2011-07-08 17:40:12 +0800238 */
239
Binghua Duan198678b2012-08-20 06:42:36 +0000240static int usb_pll_clk_enable(struct clk_hw *hw)
Binghua Duan02c981c2011-07-08 17:40:12 +0800241{
Binghua Duan198678b2012-08-20 06:42:36 +0000242 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
243 reg &= ~(SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
244 writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
245 while (!(readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL) &
246 SIRFSOC_USBPHY_PLL_LOCK))
247 cpu_relax();
248
249 return 0;
250}
251
252static void usb_pll_clk_disable(struct clk_hw *clk)
253{
254 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
255 reg |= (SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
256 writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
257}
258
259static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
260{
261 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
262 return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ;
263}
264
265static struct clk_ops usb_pll_ops = {
266 .enable = usb_pll_clk_enable,
267 .disable = usb_pll_clk_disable,
268 .recalc_rate = usb_pll_clk_recalc_rate,
269};
270
271static struct clk_init_data clk_usb_pll_init = {
272 .name = "usb_pll",
273 .ops = &usb_pll_ops,
274 .parent_names = pll_clk_parents,
275 .num_parents = ARRAY_SIZE(pll_clk_parents),
276};
277
278static struct clk_hw usb_pll_clk_hw = {
279 .init = &clk_usb_pll_init,
280};
281
282/*
283 * clock domains - cpu, mem, sys/io, dsp, gfx
284 */
285
286static const char *dmn_clk_parents[] = {
287 "rtc",
288 "osc",
289 "pll1",
290 "pll2",
291 "pll3",
292};
293
294static u8 dmn_clk_get_parent(struct clk_hw *hw)
295{
296 struct clk_dmn *clk = to_dmnclk(hw);
Binghua Duan02c981c2011-07-08 17:40:12 +0800297 u32 cfg = clkc_readl(clk->regofs);
Binghua Duan198678b2012-08-20 06:42:36 +0000298
299 /* parent of io domain can only be pll3 */
300 if (strcmp(hw->init->name, "io") == 0)
301 return 4;
302
Binghua Duan02c981c2011-07-08 17:40:12 +0800303 WARN_ON((cfg & (BIT(3) - 1)) > 4);
Binghua Duan198678b2012-08-20 06:42:36 +0000304
305 return cfg & (BIT(3) - 1);
Binghua Duan02c981c2011-07-08 17:40:12 +0800306}
307
Binghua Duan198678b2012-08-20 06:42:36 +0000308static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent)
Binghua Duan02c981c2011-07-08 17:40:12 +0800309{
Binghua Duan198678b2012-08-20 06:42:36 +0000310 struct clk_dmn *clk = to_dmnclk(hw);
Binghua Duan02c981c2011-07-08 17:40:12 +0800311 u32 cfg = clkc_readl(clk->regofs);
Binghua Duan198678b2012-08-20 06:42:36 +0000312
313 /* parent of io domain can only be pll3 */
314 if (strcmp(hw->init->name, "io") == 0)
315 return -EINVAL;
316
317 cfg &= ~(BIT(3) - 1);
318 clkc_writel(cfg | parent, clk->regofs);
319 /* BIT(3) - switching status: 1 - busy, 0 - done */
320 while (clkc_readl(clk->regofs) & BIT(3))
321 cpu_relax();
322
323 return 0;
Binghua Duan02c981c2011-07-08 17:40:12 +0800324}
325
Binghua Duan198678b2012-08-20 06:42:36 +0000326static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw,
327 unsigned long parent_rate)
328
Binghua Duan02c981c2011-07-08 17:40:12 +0800329{
Binghua Duan198678b2012-08-20 06:42:36 +0000330 unsigned long fin = parent_rate;
331 struct clk_dmn *clk = to_dmnclk(hw);
332
Binghua Duan02c981c2011-07-08 17:40:12 +0800333 u32 cfg = clkc_readl(clk->regofs);
Binghua Duan198678b2012-08-20 06:42:36 +0000334
Binghua Duan02c981c2011-07-08 17:40:12 +0800335 if (cfg & BIT(24)) {
336 /* fcd bypass mode */
Binghua Duan198678b2012-08-20 06:42:36 +0000337 return fin;
Binghua Duan02c981c2011-07-08 17:40:12 +0800338 } else {
339 /*
340 * wait count: bit[19:16], hold count: bit[23:20]
341 */
342 u32 wait = (cfg >> 16) & (BIT(4) - 1);
343 u32 hold = (cfg >> 20) & (BIT(4) - 1);
344
Binghua Duan198678b2012-08-20 06:42:36 +0000345 return fin / (wait + hold + 2);
Binghua Duan02c981c2011-07-08 17:40:12 +0800346 }
Binghua Duan02c981c2011-07-08 17:40:12 +0800347}
348
Binghua Duan198678b2012-08-20 06:42:36 +0000349static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
350 unsigned long *parent_rate)
Binghua Duan02c981c2011-07-08 17:40:12 +0800351{
352 unsigned long fin;
Binghua Duan198678b2012-08-20 06:42:36 +0000353 unsigned ratio, wait, hold;
354 unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
Binghua Duan02c981c2011-07-08 17:40:12 +0800355
Binghua Duan198678b2012-08-20 06:42:36 +0000356 fin = *parent_rate;
357 ratio = fin / rate;
358
359 if (ratio < 2)
360 ratio = 2;
361 if (ratio > BIT(bits + 1))
362 ratio = BIT(bits + 1);
363
364 wait = (ratio >> 1) - 1;
365 hold = ratio - wait - 2;
366
367 return fin / (wait + hold + 2);
368}
369
370static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
371 unsigned long parent_rate)
372{
373 struct clk_dmn *clk = to_dmnclk(hw);
374 unsigned long fin;
375 unsigned ratio, wait, hold, reg;
376 unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
377
378 fin = parent_rate;
Binghua Duan02c981c2011-07-08 17:40:12 +0800379 ratio = fin / rate;
380
381 if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
382 return -EINVAL;
383
384 WARN_ON(fin % rate);
385
386 wait = (ratio >> 1) - 1;
387 hold = ratio - wait - 2;
388
389 reg = clkc_readl(clk->regofs);
390 reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
391 reg |= (wait << 16) | (hold << 20) | BIT(25);
392 clkc_writel(reg, clk->regofs);
393
394 /* waiting FCD been effective */
395 while (clkc_readl(clk->regofs) & BIT(25))
396 cpu_relax();
397
Binghua Duan02c981c2011-07-08 17:40:12 +0800398 return 0;
399}
400
Barry Song7bf21bc2014-01-15 14:11:34 +0800401static int cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
402 unsigned long parent_rate)
403{
404 int ret1, ret2;
405 struct clk *cur_parent;
406
407 if (rate == clk_get_rate(clk_pll1.hw.clk)) {
408 ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk);
409 return ret1;
410 }
411
412 if (rate == clk_get_rate(clk_pll2.hw.clk)) {
413 ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk);
414 return ret1;
415 }
416
417 if (rate == clk_get_rate(clk_pll3.hw.clk)) {
418 ret1 = clk_set_parent(hw->clk, clk_pll3.hw.clk);
419 return ret1;
420 }
421
422 cur_parent = clk_get_parent(hw->clk);
423
424 /* switch to tmp pll before setting parent clock's rate */
425 if (cur_parent == clk_pll1.hw.clk) {
426 ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk);
427 BUG_ON(ret1);
428 }
429
430 ret2 = clk_set_rate(clk_pll1.hw.clk, rate);
431
432 ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk);
433
434 return ret2 ? ret2 : ret1;
435}
436
Binghua Duan02c981c2011-07-08 17:40:12 +0800437static struct clk_ops msi_ops = {
Binghua Duan198678b2012-08-20 06:42:36 +0000438 .set_rate = dmn_clk_set_rate,
439 .round_rate = dmn_clk_round_rate,
440 .recalc_rate = dmn_clk_recalc_rate,
441 .set_parent = dmn_clk_set_parent,
442 .get_parent = dmn_clk_get_parent,
Binghua Duan02c981c2011-07-08 17:40:12 +0800443};
444
Binghua Duan198678b2012-08-20 06:42:36 +0000445static struct clk_init_data clk_mem_init = {
446 .name = "mem",
447 .ops = &msi_ops,
448 .parent_names = dmn_clk_parents,
449 .num_parents = ARRAY_SIZE(dmn_clk_parents),
450};
451
452static struct clk_dmn clk_mem = {
Binghua Duan02c981c2011-07-08 17:40:12 +0800453 .regofs = SIRFSOC_CLKC_MEM_CFG,
Binghua Duan198678b2012-08-20 06:42:36 +0000454 .hw = {
455 .init = &clk_mem_init,
Binghua Duan02c981c2011-07-08 17:40:12 +0800456 },
457};
458
Binghua Duan198678b2012-08-20 06:42:36 +0000459static struct clk_init_data clk_sys_init = {
460 .name = "sys",
461 .ops = &msi_ops,
462 .parent_names = dmn_clk_parents,
463 .num_parents = ARRAY_SIZE(dmn_clk_parents),
464 .flags = CLK_SET_RATE_GATE,
465};
466
467static struct clk_dmn clk_sys = {
468 .regofs = SIRFSOC_CLKC_SYS_CFG,
469 .hw = {
470 .init = &clk_sys_init,
471 },
472};
473
474static struct clk_init_data clk_io_init = {
475 .name = "io",
476 .ops = &msi_ops,
477 .parent_names = dmn_clk_parents,
478 .num_parents = ARRAY_SIZE(dmn_clk_parents),
479};
480
481static struct clk_dmn clk_io = {
482 .regofs = SIRFSOC_CLKC_IO_CFG,
483 .hw = {
484 .init = &clk_io_init,
485 },
486};
487
488static struct clk_ops cpu_ops = {
489 .set_parent = dmn_clk_set_parent,
490 .get_parent = dmn_clk_get_parent,
Barry Song7bf21bc2014-01-15 14:11:34 +0800491 .set_rate = cpu_clk_set_rate,
492 .round_rate = cpu_clk_round_rate,
493 .recalc_rate = cpu_clk_recalc_rate,
Binghua Duan198678b2012-08-20 06:42:36 +0000494};
495
496static struct clk_init_data clk_cpu_init = {
497 .name = "cpu",
498 .ops = &cpu_ops,
499 .parent_names = dmn_clk_parents,
500 .num_parents = ARRAY_SIZE(dmn_clk_parents),
501 .flags = CLK_SET_RATE_PARENT,
502};
503
504static struct clk_dmn clk_cpu = {
505 .regofs = SIRFSOC_CLKC_CPU_CFG,
506 .hw = {
507 .init = &clk_cpu_init,
508 },
509};
510
511static struct clk_ops dmn_ops = {
512 .is_enabled = std_clk_is_enabled,
513 .enable = std_clk_enable,
514 .disable = std_clk_disable,
515 .set_rate = dmn_clk_set_rate,
516 .round_rate = dmn_clk_round_rate,
517 .recalc_rate = dmn_clk_recalc_rate,
518 .set_parent = dmn_clk_set_parent,
519 .get_parent = dmn_clk_get_parent,
520};
521
522/* dsp, gfx, mm, lcd and vpp domain */
523
524static struct clk_init_data clk_dsp_init = {
525 .name = "dsp",
526 .ops = &dmn_ops,
527 .parent_names = dmn_clk_parents,
528 .num_parents = ARRAY_SIZE(dmn_clk_parents),
529};
530
531static struct clk_dmn clk_dsp = {
532 .regofs = SIRFSOC_CLKC_DSP_CFG,
533 .enable_bit = 0,
534 .hw = {
535 .init = &clk_dsp_init,
536 },
537};
538
539static struct clk_init_data clk_gfx_init = {
540 .name = "gfx",
541 .ops = &dmn_ops,
542 .parent_names = dmn_clk_parents,
543 .num_parents = ARRAY_SIZE(dmn_clk_parents),
544};
545
546static struct clk_dmn clk_gfx = {
547 .regofs = SIRFSOC_CLKC_GFX_CFG,
548 .enable_bit = 8,
549 .hw = {
550 .init = &clk_gfx_init,
551 },
552};
553
554static struct clk_init_data clk_mm_init = {
555 .name = "mm",
556 .ops = &dmn_ops,
557 .parent_names = dmn_clk_parents,
558 .num_parents = ARRAY_SIZE(dmn_clk_parents),
559};
560
561static struct clk_dmn clk_mm = {
562 .regofs = SIRFSOC_CLKC_MM_CFG,
563 .enable_bit = 9,
564 .hw = {
565 .init = &clk_mm_init,
566 },
567};
568
Barry Song7bf21bc2014-01-15 14:11:34 +0800569/*
570 * for atlas6, gfx2d holds the bit of prima2's clk_mm
571 */
572#define clk_gfx2d clk_mm
573
Binghua Duan198678b2012-08-20 06:42:36 +0000574static struct clk_init_data clk_lcd_init = {
575 .name = "lcd",
576 .ops = &dmn_ops,
577 .parent_names = dmn_clk_parents,
578 .num_parents = ARRAY_SIZE(dmn_clk_parents),
579};
580
581static struct clk_dmn clk_lcd = {
582 .regofs = SIRFSOC_CLKC_LCD_CFG,
583 .enable_bit = 10,
584 .hw = {
585 .init = &clk_lcd_init,
586 },
587};
588
589static struct clk_init_data clk_vpp_init = {
590 .name = "vpp",
591 .ops = &dmn_ops,
592 .parent_names = dmn_clk_parents,
593 .num_parents = ARRAY_SIZE(dmn_clk_parents),
594};
595
596static struct clk_dmn clk_vpp = {
597 .regofs = SIRFSOC_CLKC_LCD_CFG,
598 .enable_bit = 11,
599 .hw = {
600 .init = &clk_vpp_init,
601 },
602};
603
604static struct clk_init_data clk_mmc01_init = {
605 .name = "mmc01",
606 .ops = &dmn_ops,
607 .parent_names = dmn_clk_parents,
608 .num_parents = ARRAY_SIZE(dmn_clk_parents),
609};
610
Binghua Duan198678b2012-08-20 06:42:36 +0000611static struct clk_init_data clk_mmc23_init = {
612 .name = "mmc23",
613 .ops = &dmn_ops,
614 .parent_names = dmn_clk_parents,
615 .num_parents = ARRAY_SIZE(dmn_clk_parents),
616};
617
Binghua Duan198678b2012-08-20 06:42:36 +0000618static struct clk_init_data clk_mmc45_init = {
619 .name = "mmc45",
620 .ops = &dmn_ops,
621 .parent_names = dmn_clk_parents,
622 .num_parents = ARRAY_SIZE(dmn_clk_parents),
623};
624
Binghua Duan198678b2012-08-20 06:42:36 +0000625/*
626 * peripheral controllers in io domain
627 */
628
629static int std_clk_is_enabled(struct clk_hw *hw)
Binghua Duan02c981c2011-07-08 17:40:12 +0800630{
Binghua Duan198678b2012-08-20 06:42:36 +0000631 u32 reg;
632 int bit;
633 struct clk_std *clk = to_stdclk(hw);
Binghua Duan02c981c2011-07-08 17:40:12 +0800634
Binghua Duan198678b2012-08-20 06:42:36 +0000635 bit = clk->enable_bit % 32;
636 reg = clk->enable_bit / 32;
637 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
Binghua Duan02c981c2011-07-08 17:40:12 +0800638
Binghua Duan198678b2012-08-20 06:42:36 +0000639 return !!(clkc_readl(reg) & BIT(bit));
640}
Binghua Duan02c981c2011-07-08 17:40:12 +0800641
Binghua Duan198678b2012-08-20 06:42:36 +0000642static int std_clk_enable(struct clk_hw *hw)
643{
644 u32 val, reg;
645 int bit;
646 struct clk_std *clk = to_stdclk(hw);
647
648 BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
649
650 bit = clk->enable_bit % 32;
651 reg = clk->enable_bit / 32;
652 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
653
654 val = clkc_readl(reg) | BIT(bit);
655 clkc_writel(val, reg);
Binghua Duan02c981c2011-07-08 17:40:12 +0800656 return 0;
657}
Binghua Duan02c981c2011-07-08 17:40:12 +0800658
Binghua Duan198678b2012-08-20 06:42:36 +0000659static void std_clk_disable(struct clk_hw *hw)
Binghua Duan02c981c2011-07-08 17:40:12 +0800660{
Binghua Duan198678b2012-08-20 06:42:36 +0000661 u32 val, reg;
662 int bit;
663 struct clk_std *clk = to_stdclk(hw);
Binghua Duan02c981c2011-07-08 17:40:12 +0800664
Binghua Duan198678b2012-08-20 06:42:36 +0000665 BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
Binghua Duan02c981c2011-07-08 17:40:12 +0800666
Binghua Duan198678b2012-08-20 06:42:36 +0000667 bit = clk->enable_bit % 32;
668 reg = clk->enable_bit / 32;
669 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
Binghua Duan02c981c2011-07-08 17:40:12 +0800670
Binghua Duan198678b2012-08-20 06:42:36 +0000671 val = clkc_readl(reg) & ~BIT(bit);
672 clkc_writel(val, reg);
Binghua Duan02c981c2011-07-08 17:40:12 +0800673}
Binghua Duan02c981c2011-07-08 17:40:12 +0800674
Binghua Duan198678b2012-08-20 06:42:36 +0000675static const char *std_clk_io_parents[] = {
676 "io",
677};
Binghua Duan02c981c2011-07-08 17:40:12 +0800678
Binghua Duan198678b2012-08-20 06:42:36 +0000679static struct clk_ops ios_ops = {
680 .is_enabled = std_clk_is_enabled,
681 .enable = std_clk_enable,
682 .disable = std_clk_disable,
683};
Binghua Duan02c981c2011-07-08 17:40:12 +0800684
Barry Song7bf21bc2014-01-15 14:11:34 +0800685static struct clk_init_data clk_cphif_init = {
686 .name = "cphif",
687 .ops = &ios_ops,
688 .parent_names = std_clk_io_parents,
689 .num_parents = ARRAY_SIZE(std_clk_io_parents),
690};
691
692static struct clk_std clk_cphif = {
693 .enable_bit = 20,
694 .hw = {
695 .init = &clk_cphif_init,
696 },
697};
698
Binghua Duan198678b2012-08-20 06:42:36 +0000699static struct clk_init_data clk_dmac0_init = {
700 .name = "dmac0",
701 .ops = &ios_ops,
702 .parent_names = std_clk_io_parents,
703 .num_parents = ARRAY_SIZE(std_clk_io_parents),
704};
Binghua Duan02c981c2011-07-08 17:40:12 +0800705
Binghua Duan198678b2012-08-20 06:42:36 +0000706static struct clk_std clk_dmac0 = {
707 .enable_bit = 32,
708 .hw = {
709 .init = &clk_dmac0_init,
710 },
711};
Binghua Duan02c981c2011-07-08 17:40:12 +0800712
Binghua Duan198678b2012-08-20 06:42:36 +0000713static struct clk_init_data clk_dmac1_init = {
714 .name = "dmac1",
715 .ops = &ios_ops,
716 .parent_names = std_clk_io_parents,
717 .num_parents = ARRAY_SIZE(std_clk_io_parents),
718};
Binghua Duan02c981c2011-07-08 17:40:12 +0800719
Binghua Duan198678b2012-08-20 06:42:36 +0000720static struct clk_std clk_dmac1 = {
721 .enable_bit = 33,
722 .hw = {
723 .init = &clk_dmac1_init,
724 },
725};
Binghua Duan02c981c2011-07-08 17:40:12 +0800726
Binghua Duan198678b2012-08-20 06:42:36 +0000727static struct clk_init_data clk_audio_init = {
728 .name = "audio",
729 .ops = &ios_ops,
730 .parent_names = std_clk_io_parents,
731 .num_parents = ARRAY_SIZE(std_clk_io_parents),
732};
Binghua Duan02c981c2011-07-08 17:40:12 +0800733
Binghua Duan198678b2012-08-20 06:42:36 +0000734static struct clk_std clk_audio = {
735 .enable_bit = 35,
736 .hw = {
737 .init = &clk_audio_init,
738 },
739};
Binghua Duan02c981c2011-07-08 17:40:12 +0800740
Binghua Duan198678b2012-08-20 06:42:36 +0000741static struct clk_init_data clk_uart0_init = {
742 .name = "uart0",
743 .ops = &ios_ops,
744 .parent_names = std_clk_io_parents,
745 .num_parents = ARRAY_SIZE(std_clk_io_parents),
746};
Binghua Duan02c981c2011-07-08 17:40:12 +0800747
Binghua Duan198678b2012-08-20 06:42:36 +0000748static struct clk_std clk_uart0 = {
749 .enable_bit = 36,
750 .hw = {
751 .init = &clk_uart0_init,
752 },
753};
Binghua Duan02c981c2011-07-08 17:40:12 +0800754
Binghua Duan198678b2012-08-20 06:42:36 +0000755static struct clk_init_data clk_uart1_init = {
756 .name = "uart1",
757 .ops = &ios_ops,
758 .parent_names = std_clk_io_parents,
759 .num_parents = ARRAY_SIZE(std_clk_io_parents),
760};
Binghua Duan02c981c2011-07-08 17:40:12 +0800761
Binghua Duan198678b2012-08-20 06:42:36 +0000762static struct clk_std clk_uart1 = {
763 .enable_bit = 37,
764 .hw = {
765 .init = &clk_uart1_init,
766 },
767};
Binghua Duan02c981c2011-07-08 17:40:12 +0800768
Binghua Duan198678b2012-08-20 06:42:36 +0000769static struct clk_init_data clk_uart2_init = {
770 .name = "uart2",
771 .ops = &ios_ops,
772 .parent_names = std_clk_io_parents,
773 .num_parents = ARRAY_SIZE(std_clk_io_parents),
774};
Binghua Duan02c981c2011-07-08 17:40:12 +0800775
Binghua Duan198678b2012-08-20 06:42:36 +0000776static struct clk_std clk_uart2 = {
777 .enable_bit = 38,
778 .hw = {
779 .init = &clk_uart2_init,
780 },
781};
Binghua Duan02c981c2011-07-08 17:40:12 +0800782
Binghua Duan198678b2012-08-20 06:42:36 +0000783static struct clk_init_data clk_usp0_init = {
784 .name = "usp0",
785 .ops = &ios_ops,
786 .parent_names = std_clk_io_parents,
787 .num_parents = ARRAY_SIZE(std_clk_io_parents),
788};
Binghua Duan02c981c2011-07-08 17:40:12 +0800789
Binghua Duan198678b2012-08-20 06:42:36 +0000790static struct clk_std clk_usp0 = {
791 .enable_bit = 39,
792 .hw = {
793 .init = &clk_usp0_init,
794 },
795};
Binghua Duan02c981c2011-07-08 17:40:12 +0800796
Binghua Duan198678b2012-08-20 06:42:36 +0000797static struct clk_init_data clk_usp1_init = {
798 .name = "usp1",
799 .ops = &ios_ops,
800 .parent_names = std_clk_io_parents,
801 .num_parents = ARRAY_SIZE(std_clk_io_parents),
802};
803
804static struct clk_std clk_usp1 = {
805 .enable_bit = 40,
806 .hw = {
807 .init = &clk_usp1_init,
808 },
809};
810
811static struct clk_init_data clk_usp2_init = {
812 .name = "usp2",
813 .ops = &ios_ops,
814 .parent_names = std_clk_io_parents,
815 .num_parents = ARRAY_SIZE(std_clk_io_parents),
816};
817
818static struct clk_std clk_usp2 = {
819 .enable_bit = 41,
820 .hw = {
821 .init = &clk_usp2_init,
822 },
823};
824
825static struct clk_init_data clk_vip_init = {
826 .name = "vip",
827 .ops = &ios_ops,
828 .parent_names = std_clk_io_parents,
829 .num_parents = ARRAY_SIZE(std_clk_io_parents),
830};
831
832static struct clk_std clk_vip = {
833 .enable_bit = 42,
834 .hw = {
835 .init = &clk_vip_init,
836 },
837};
838
839static struct clk_init_data clk_spi0_init = {
840 .name = "spi0",
841 .ops = &ios_ops,
842 .parent_names = std_clk_io_parents,
843 .num_parents = ARRAY_SIZE(std_clk_io_parents),
844};
845
846static struct clk_std clk_spi0 = {
847 .enable_bit = 43,
848 .hw = {
849 .init = &clk_spi0_init,
850 },
851};
852
853static struct clk_init_data clk_spi1_init = {
854 .name = "spi1",
855 .ops = &ios_ops,
856 .parent_names = std_clk_io_parents,
857 .num_parents = ARRAY_SIZE(std_clk_io_parents),
858};
859
860static struct clk_std clk_spi1 = {
861 .enable_bit = 44,
862 .hw = {
863 .init = &clk_spi1_init,
864 },
865};
866
867static struct clk_init_data clk_tsc_init = {
868 .name = "tsc",
869 .ops = &ios_ops,
870 .parent_names = std_clk_io_parents,
871 .num_parents = ARRAY_SIZE(std_clk_io_parents),
872};
873
874static struct clk_std clk_tsc = {
875 .enable_bit = 45,
876 .hw = {
877 .init = &clk_tsc_init,
878 },
879};
880
881static struct clk_init_data clk_i2c0_init = {
882 .name = "i2c0",
883 .ops = &ios_ops,
884 .parent_names = std_clk_io_parents,
885 .num_parents = ARRAY_SIZE(std_clk_io_parents),
886};
887
888static struct clk_std clk_i2c0 = {
889 .enable_bit = 46,
890 .hw = {
891 .init = &clk_i2c0_init,
892 },
893};
894
895static struct clk_init_data clk_i2c1_init = {
896 .name = "i2c1",
897 .ops = &ios_ops,
898 .parent_names = std_clk_io_parents,
899 .num_parents = ARRAY_SIZE(std_clk_io_parents),
900};
901
902static struct clk_std clk_i2c1 = {
903 .enable_bit = 47,
904 .hw = {
905 .init = &clk_i2c1_init,
906 },
907};
908
909static struct clk_init_data clk_pwmc_init = {
910 .name = "pwmc",
911 .ops = &ios_ops,
912 .parent_names = std_clk_io_parents,
913 .num_parents = ARRAY_SIZE(std_clk_io_parents),
914};
915
916static struct clk_std clk_pwmc = {
917 .enable_bit = 48,
918 .hw = {
919 .init = &clk_pwmc_init,
920 },
921};
922
923static struct clk_init_data clk_efuse_init = {
924 .name = "efuse",
925 .ops = &ios_ops,
926 .parent_names = std_clk_io_parents,
927 .num_parents = ARRAY_SIZE(std_clk_io_parents),
928};
929
930static struct clk_std clk_efuse = {
931 .enable_bit = 49,
932 .hw = {
933 .init = &clk_efuse_init,
934 },
935};
936
937static struct clk_init_data clk_pulse_init = {
938 .name = "pulse",
939 .ops = &ios_ops,
940 .parent_names = std_clk_io_parents,
941 .num_parents = ARRAY_SIZE(std_clk_io_parents),
942};
943
944static struct clk_std clk_pulse = {
945 .enable_bit = 50,
946 .hw = {
947 .init = &clk_pulse_init,
948 },
949};
950
951static const char *std_clk_dsp_parents[] = {
952 "dsp",
953};
954
955static struct clk_init_data clk_gps_init = {
956 .name = "gps",
957 .ops = &ios_ops,
958 .parent_names = std_clk_dsp_parents,
959 .num_parents = ARRAY_SIZE(std_clk_dsp_parents),
960};
961
962static struct clk_std clk_gps = {
963 .enable_bit = 1,
964 .hw = {
965 .init = &clk_gps_init,
966 },
967};
968
969static struct clk_init_data clk_mf_init = {
970 .name = "mf",
971 .ops = &ios_ops,
972 .parent_names = std_clk_io_parents,
973 .num_parents = ARRAY_SIZE(std_clk_io_parents),
974};
975
976static struct clk_std clk_mf = {
977 .enable_bit = 2,
978 .hw = {
979 .init = &clk_mf_init,
980 },
981};
982
983static const char *std_clk_sys_parents[] = {
984 "sys",
985};
986
987static struct clk_init_data clk_security_init = {
Barry Song7bf21bc2014-01-15 14:11:34 +0800988 .name = "security",
Binghua Duan198678b2012-08-20 06:42:36 +0000989 .ops = &ios_ops,
990 .parent_names = std_clk_sys_parents,
991 .num_parents = ARRAY_SIZE(std_clk_sys_parents),
992};
993
994static struct clk_std clk_security = {
995 .enable_bit = 19,
996 .hw = {
997 .init = &clk_security_init,
998 },
999};
1000
1001static const char *std_clk_usb_parents[] = {
1002 "usb_pll",
1003};
1004
1005static struct clk_init_data clk_usb0_init = {
1006 .name = "usb0",
1007 .ops = &ios_ops,
1008 .parent_names = std_clk_usb_parents,
1009 .num_parents = ARRAY_SIZE(std_clk_usb_parents),
1010};
1011
1012static struct clk_std clk_usb0 = {
1013 .enable_bit = 16,
1014 .hw = {
1015 .init = &clk_usb0_init,
1016 },
1017};
1018
1019static struct clk_init_data clk_usb1_init = {
1020 .name = "usb1",
1021 .ops = &ios_ops,
1022 .parent_names = std_clk_usb_parents,
1023 .num_parents = ARRAY_SIZE(std_clk_usb_parents),
1024};
1025
1026static struct clk_std clk_usb1 = {
1027 .enable_bit = 17,
1028 .hw = {
1029 .init = &clk_usb1_init,
1030 },
1031};