Root/drivers/clk/clk-prima2.c

1/*
2 * Clock tree for CSR SiRFprimaII
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/module.h>
10#include <linux/bitops.h>
11#include <linux/io.h>
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/clk-provider.h>
15#include <linux/of_address.h>
16#include <linux/syscore_ops.h>
17
18#define SIRFSOC_CLKC_CLK_EN0 0x0000
19#define SIRFSOC_CLKC_CLK_EN1 0x0004
20#define SIRFSOC_CLKC_REF_CFG 0x0014
21#define SIRFSOC_CLKC_CPU_CFG 0x0018
22#define SIRFSOC_CLKC_MEM_CFG 0x001c
23#define SIRFSOC_CLKC_SYS_CFG 0x0020
24#define SIRFSOC_CLKC_IO_CFG 0x0024
25#define SIRFSOC_CLKC_DSP_CFG 0x0028
26#define SIRFSOC_CLKC_GFX_CFG 0x002c
27#define SIRFSOC_CLKC_MM_CFG 0x0030
28#define SIRFSOC_CLKC_LCD_CFG 0x0034
29#define SIRFSOC_CLKC_MMC_CFG 0x0038
30#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
31#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
32#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
33#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
34#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
35#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
36#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
37#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
38#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
39#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
40#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
41#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
42#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)
43
44static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase;
45
46#define KHZ 1000
47#define MHZ (KHZ * KHZ)
48
49/*
50 * SiRFprimaII clock controller
51 * - 2 oscillators: osc-26MHz, rtc-32.768KHz
52 * - 3 standard configurable plls: pll1, pll2 & pll3
53 * - 2 exclusive plls: usb phy pll and sata phy pll
54 * - 8 clock domains: cpu/cpudiv, mem/memdiv, sys/io, dsp, graphic, multimedia,
55 * display and sdphy.
56 * Each clock domain can select its own clock source from five clock sources,
57 * X_XIN, X_XINW, PLL1, PLL2 and PLL3. The domain clock is used as the source
58 * clock of the group clock.
59 * - dsp domain: gps, mf
60 * - io domain: dmac, nand, audio, uart, i2c, spi, usp, pwm, pulse
61 * - sys domain: security
62 */
63
64struct clk_pll {
65    struct clk_hw hw;
66    unsigned short regofs; /* register offset */
67};
68
69#define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
70
71struct clk_dmn {
72    struct clk_hw hw;
73    signed char enable_bit; /* enable bit: 0 ~ 63 */
74    unsigned short regofs; /* register offset */
75};
76
77#define to_dmnclk(_hw) container_of(_hw, struct clk_dmn, hw)
78
79struct clk_std {
80    struct clk_hw hw;
81    signed char enable_bit; /* enable bit: 0 ~ 63 */
82};
83
84#define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
85
86static int std_clk_is_enabled(struct clk_hw *hw);
87static int std_clk_enable(struct clk_hw *hw);
88static void std_clk_disable(struct clk_hw *hw);
89
90static inline unsigned long clkc_readl(unsigned reg)
91{
92    return readl(sirfsoc_clk_vbase + reg);
93}
94
95static inline void clkc_writel(u32 val, unsigned reg)
96{
97    writel(val, sirfsoc_clk_vbase + reg);
98}
99
100/*
101 * std pll
102 */
103
104static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
105    unsigned long parent_rate)
106{
107    unsigned long fin = parent_rate;
108    struct clk_pll *clk = to_pllclk(hw);
109    u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
110        SIRFSOC_CLKC_PLL1_CFG0;
111
112    if (clkc_readl(regcfg2) & BIT(2)) {
113        /* pll bypass mode */
114        return fin;
115    } else {
116        /* fout = fin * nf / nr / od */
117        u32 cfg0 = clkc_readl(clk->regofs);
118        u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
119        u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
120        u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
121        WARN_ON(fin % MHZ);
122        return fin / MHZ * nf / nr / od * MHZ;
123    }
124}
125
126static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
127    unsigned long *parent_rate)
128{
129    unsigned long fin, nf, nr, od;
130
131    /*
132     * fout = fin * nf / (nr * od);
133     * set od = 1, nr = fin/MHz, so fout = nf * MHz
134     */
135    rate = rate - rate % MHZ;
136
137    nf = rate / MHZ;
138    if (nf > BIT(13))
139        nf = BIT(13);
140    if (nf < 1)
141        nf = 1;
142
143    fin = *parent_rate;
144
145    nr = fin / MHZ;
146    if (nr > BIT(6))
147        nr = BIT(6);
148    od = 1;
149
150    return fin * nf / (nr * od);
151}
152
153static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
154    unsigned long parent_rate)
155{
156    struct clk_pll *clk = to_pllclk(hw);
157    unsigned long fin, nf, nr, od, reg;
158
159    /*
160     * fout = fin * nf / (nr * od);
161     * set od = 1, nr = fin/MHz, so fout = nf * MHz
162     */
163
164    nf = rate / MHZ;
165    if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
166        return -EINVAL;
167
168    fin = parent_rate;
169    BUG_ON(fin < MHZ);
170
171    nr = fin / MHZ;
172    BUG_ON((fin % MHZ) || nr > BIT(6));
173
174    od = 1;
175
176    reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
177    clkc_writel(reg, clk->regofs);
178
179    reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
180    clkc_writel((nf >> 1) - 1, reg);
181
182    reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
183    while (!(clkc_readl(reg) & BIT(6)))
184        cpu_relax();
185
186    return 0;
187}
188
189static struct clk_ops std_pll_ops = {
190    .recalc_rate = pll_clk_recalc_rate,
191    .round_rate = pll_clk_round_rate,
192    .set_rate = pll_clk_set_rate,
193};
194
195static const char *pll_clk_parents[] = {
196    "osc",
197};
198
199static struct clk_init_data clk_pll1_init = {
200    .name = "pll1",
201    .ops = &std_pll_ops,
202    .parent_names = pll_clk_parents,
203    .num_parents = ARRAY_SIZE(pll_clk_parents),
204};
205
206static struct clk_init_data clk_pll2_init = {
207    .name = "pll2",
208    .ops = &std_pll_ops,
209    .parent_names = pll_clk_parents,
210    .num_parents = ARRAY_SIZE(pll_clk_parents),
211};
212
213static struct clk_init_data clk_pll3_init = {
214    .name = "pll3",
215    .ops = &std_pll_ops,
216    .parent_names = pll_clk_parents,
217    .num_parents = ARRAY_SIZE(pll_clk_parents),
218};
219
220static struct clk_pll clk_pll1 = {
221    .regofs = SIRFSOC_CLKC_PLL1_CFG0,
222    .hw = {
223        .init = &clk_pll1_init,
224    },
225};
226
227static struct clk_pll clk_pll2 = {
228    .regofs = SIRFSOC_CLKC_PLL2_CFG0,
229    .hw = {
230        .init = &clk_pll2_init,
231    },
232};
233
234static struct clk_pll clk_pll3 = {
235    .regofs = SIRFSOC_CLKC_PLL3_CFG0,
236    .hw = {
237        .init = &clk_pll3_init,
238    },
239};
240
241/*
242 * usb uses specified pll
243 */
244
245static int usb_pll_clk_enable(struct clk_hw *hw)
246{
247    u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
248    reg &= ~(SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
249    writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
250    while (!(readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL) &
251            SIRFSOC_USBPHY_PLL_LOCK))
252        cpu_relax();
253
254    return 0;
255}
256
257static void usb_pll_clk_disable(struct clk_hw *clk)
258{
259    u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
260    reg |= (SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
261    writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
262}
263
264static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
265{
266    u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
267    return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ;
268}
269
270static struct clk_ops usb_pll_ops = {
271    .enable = usb_pll_clk_enable,
272    .disable = usb_pll_clk_disable,
273    .recalc_rate = usb_pll_clk_recalc_rate,
274};
275
276static struct clk_init_data clk_usb_pll_init = {
277    .name = "usb_pll",
278    .ops = &usb_pll_ops,
279    .parent_names = pll_clk_parents,
280    .num_parents = ARRAY_SIZE(pll_clk_parents),
281};
282
283static struct clk_hw usb_pll_clk_hw = {
284    .init = &clk_usb_pll_init,
285};
286
287/*
288 * clock domains - cpu, mem, sys/io, dsp, gfx
289 */
290
291static const char *dmn_clk_parents[] = {
292    "rtc",
293    "osc",
294    "pll1",
295    "pll2",
296    "pll3",
297};
298
299static u8 dmn_clk_get_parent(struct clk_hw *hw)
300{
301    struct clk_dmn *clk = to_dmnclk(hw);
302    u32 cfg = clkc_readl(clk->regofs);
303
304    /* parent of io domain can only be pll3 */
305    if (strcmp(hw->init->name, "io") == 0)
306        return 4;
307
308    WARN_ON((cfg & (BIT(3) - 1)) > 4);
309
310    return cfg & (BIT(3) - 1);
311}
312
313static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent)
314{
315    struct clk_dmn *clk = to_dmnclk(hw);
316    u32 cfg = clkc_readl(clk->regofs);
317
318    /* parent of io domain can only be pll3 */
319    if (strcmp(hw->init->name, "io") == 0)
320        return -EINVAL;
321
322    cfg &= ~(BIT(3) - 1);
323    clkc_writel(cfg | parent, clk->regofs);
324    /* BIT(3) - switching status: 1 - busy, 0 - done */
325    while (clkc_readl(clk->regofs) & BIT(3))
326        cpu_relax();
327
328    return 0;
329}
330
331static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw,
332    unsigned long parent_rate)
333
334{
335    unsigned long fin = parent_rate;
336    struct clk_dmn *clk = to_dmnclk(hw);
337
338    u32 cfg = clkc_readl(clk->regofs);
339
340    if (cfg & BIT(24)) {
341        /* fcd bypass mode */
342        return fin;
343    } else {
344        /*
345         * wait count: bit[19:16], hold count: bit[23:20]
346         */
347        u32 wait = (cfg >> 16) & (BIT(4) - 1);
348        u32 hold = (cfg >> 20) & (BIT(4) - 1);
349
350        return fin / (wait + hold + 2);
351    }
352}
353
354static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
355    unsigned long *parent_rate)
356{
357    unsigned long fin;
358    unsigned ratio, wait, hold;
359    unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
360
361    fin = *parent_rate;
362    ratio = fin / rate;
363
364    if (ratio < 2)
365        ratio = 2;
366    if (ratio > BIT(bits + 1))
367        ratio = BIT(bits + 1);
368
369    wait = (ratio >> 1) - 1;
370    hold = ratio - wait - 2;
371
372    return fin / (wait + hold + 2);
373}
374
375static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
376    unsigned long parent_rate)
377{
378    struct clk_dmn *clk = to_dmnclk(hw);
379    unsigned long fin;
380    unsigned ratio, wait, hold, reg;
381    unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
382
383    fin = parent_rate;
384    ratio = fin / rate;
385
386    if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
387        return -EINVAL;
388
389    WARN_ON(fin % rate);
390
391    wait = (ratio >> 1) - 1;
392    hold = ratio - wait - 2;
393
394    reg = clkc_readl(clk->regofs);
395    reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
396    reg |= (wait << 16) | (hold << 20) | BIT(25);
397    clkc_writel(reg, clk->regofs);
398
399    /* waiting FCD been effective */
400    while (clkc_readl(clk->regofs) & BIT(25))
401        cpu_relax();
402
403    return 0;
404}
405
406static struct clk_ops msi_ops = {
407    .set_rate = dmn_clk_set_rate,
408    .round_rate = dmn_clk_round_rate,
409    .recalc_rate = dmn_clk_recalc_rate,
410    .set_parent = dmn_clk_set_parent,
411    .get_parent = dmn_clk_get_parent,
412};
413
414static struct clk_init_data clk_mem_init = {
415    .name = "mem",
416    .ops = &msi_ops,
417    .parent_names = dmn_clk_parents,
418    .num_parents = ARRAY_SIZE(dmn_clk_parents),
419};
420
421static struct clk_dmn clk_mem = {
422    .regofs = SIRFSOC_CLKC_MEM_CFG,
423    .hw = {
424        .init = &clk_mem_init,
425    },
426};
427
428static struct clk_init_data clk_sys_init = {
429    .name = "sys",
430    .ops = &msi_ops,
431    .parent_names = dmn_clk_parents,
432    .num_parents = ARRAY_SIZE(dmn_clk_parents),
433    .flags = CLK_SET_RATE_GATE,
434};
435
436static struct clk_dmn clk_sys = {
437    .regofs = SIRFSOC_CLKC_SYS_CFG,
438    .hw = {
439        .init = &clk_sys_init,
440    },
441};
442
443static struct clk_init_data clk_io_init = {
444    .name = "io",
445    .ops = &msi_ops,
446    .parent_names = dmn_clk_parents,
447    .num_parents = ARRAY_SIZE(dmn_clk_parents),
448};
449
450static struct clk_dmn clk_io = {
451    .regofs = SIRFSOC_CLKC_IO_CFG,
452    .hw = {
453        .init = &clk_io_init,
454    },
455};
456
457static struct clk_ops cpu_ops = {
458    .set_parent = dmn_clk_set_parent,
459    .get_parent = dmn_clk_get_parent,
460};
461
462static struct clk_init_data clk_cpu_init = {
463    .name = "cpu",
464    .ops = &cpu_ops,
465    .parent_names = dmn_clk_parents,
466    .num_parents = ARRAY_SIZE(dmn_clk_parents),
467    .flags = CLK_SET_RATE_PARENT,
468};
469
470static struct clk_dmn clk_cpu = {
471    .regofs = SIRFSOC_CLKC_CPU_CFG,
472    .hw = {
473        .init = &clk_cpu_init,
474    },
475};
476
477static struct clk_ops dmn_ops = {
478    .is_enabled = std_clk_is_enabled,
479    .enable = std_clk_enable,
480    .disable = std_clk_disable,
481    .set_rate = dmn_clk_set_rate,
482    .round_rate = dmn_clk_round_rate,
483    .recalc_rate = dmn_clk_recalc_rate,
484    .set_parent = dmn_clk_set_parent,
485    .get_parent = dmn_clk_get_parent,
486};
487
488/* dsp, gfx, mm, lcd and vpp domain */
489
490static struct clk_init_data clk_dsp_init = {
491    .name = "dsp",
492    .ops = &dmn_ops,
493    .parent_names = dmn_clk_parents,
494    .num_parents = ARRAY_SIZE(dmn_clk_parents),
495};
496
497static struct clk_dmn clk_dsp = {
498    .regofs = SIRFSOC_CLKC_DSP_CFG,
499    .enable_bit = 0,
500    .hw = {
501        .init = &clk_dsp_init,
502    },
503};
504
505static struct clk_init_data clk_gfx_init = {
506    .name = "gfx",
507    .ops = &dmn_ops,
508    .parent_names = dmn_clk_parents,
509    .num_parents = ARRAY_SIZE(dmn_clk_parents),
510};
511
512static struct clk_dmn clk_gfx = {
513    .regofs = SIRFSOC_CLKC_GFX_CFG,
514    .enable_bit = 8,
515    .hw = {
516        .init = &clk_gfx_init,
517    },
518};
519
520static struct clk_init_data clk_mm_init = {
521    .name = "mm",
522    .ops = &dmn_ops,
523    .parent_names = dmn_clk_parents,
524    .num_parents = ARRAY_SIZE(dmn_clk_parents),
525};
526
527static struct clk_dmn clk_mm = {
528    .regofs = SIRFSOC_CLKC_MM_CFG,
529    .enable_bit = 9,
530    .hw = {
531        .init = &clk_mm_init,
532    },
533};
534
535static struct clk_init_data clk_lcd_init = {
536    .name = "lcd",
537    .ops = &dmn_ops,
538    .parent_names = dmn_clk_parents,
539    .num_parents = ARRAY_SIZE(dmn_clk_parents),
540};
541
542static struct clk_dmn clk_lcd = {
543    .regofs = SIRFSOC_CLKC_LCD_CFG,
544    .enable_bit = 10,
545    .hw = {
546        .init = &clk_lcd_init,
547    },
548};
549
550static struct clk_init_data clk_vpp_init = {
551    .name = "vpp",
552    .ops = &dmn_ops,
553    .parent_names = dmn_clk_parents,
554    .num_parents = ARRAY_SIZE(dmn_clk_parents),
555};
556
557static struct clk_dmn clk_vpp = {
558    .regofs = SIRFSOC_CLKC_LCD_CFG,
559    .enable_bit = 11,
560    .hw = {
561        .init = &clk_vpp_init,
562    },
563};
564
565static struct clk_init_data clk_mmc01_init = {
566    .name = "mmc01",
567    .ops = &dmn_ops,
568    .parent_names = dmn_clk_parents,
569    .num_parents = ARRAY_SIZE(dmn_clk_parents),
570};
571
572static struct clk_dmn clk_mmc01 = {
573    .regofs = SIRFSOC_CLKC_MMC_CFG,
574    .enable_bit = 59,
575    .hw = {
576        .init = &clk_mmc01_init,
577    },
578};
579
580static struct clk_init_data clk_mmc23_init = {
581    .name = "mmc23",
582    .ops = &dmn_ops,
583    .parent_names = dmn_clk_parents,
584    .num_parents = ARRAY_SIZE(dmn_clk_parents),
585};
586
587static struct clk_dmn clk_mmc23 = {
588    .regofs = SIRFSOC_CLKC_MMC_CFG,
589    .enable_bit = 60,
590    .hw = {
591        .init = &clk_mmc23_init,
592    },
593};
594
595static struct clk_init_data clk_mmc45_init = {
596    .name = "mmc45",
597    .ops = &dmn_ops,
598    .parent_names = dmn_clk_parents,
599    .num_parents = ARRAY_SIZE(dmn_clk_parents),
600};
601
602static struct clk_dmn clk_mmc45 = {
603    .regofs = SIRFSOC_CLKC_MMC_CFG,
604    .enable_bit = 61,
605    .hw = {
606        .init = &clk_mmc45_init,
607    },
608};
609
610/*
611 * peripheral controllers in io domain
612 */
613
614static int std_clk_is_enabled(struct clk_hw *hw)
615{
616    u32 reg;
617    int bit;
618    struct clk_std *clk = to_stdclk(hw);
619
620    bit = clk->enable_bit % 32;
621    reg = clk->enable_bit / 32;
622    reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
623
624    return !!(clkc_readl(reg) & BIT(bit));
625}
626
627static int std_clk_enable(struct clk_hw *hw)
628{
629    u32 val, reg;
630    int bit;
631    struct clk_std *clk = to_stdclk(hw);
632
633    BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
634
635    bit = clk->enable_bit % 32;
636    reg = clk->enable_bit / 32;
637    reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
638
639    val = clkc_readl(reg) | BIT(bit);
640    clkc_writel(val, reg);
641    return 0;
642}
643
644static void std_clk_disable(struct clk_hw *hw)
645{
646    u32 val, reg;
647    int bit;
648    struct clk_std *clk = to_stdclk(hw);
649
650    BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
651
652    bit = clk->enable_bit % 32;
653    reg = clk->enable_bit / 32;
654    reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
655
656    val = clkc_readl(reg) & ~BIT(bit);
657    clkc_writel(val, reg);
658}
659
660static const char *std_clk_io_parents[] = {
661    "io",
662};
663
664static struct clk_ops ios_ops = {
665    .is_enabled = std_clk_is_enabled,
666    .enable = std_clk_enable,
667    .disable = std_clk_disable,
668};
669
670static struct clk_init_data clk_dmac0_init = {
671    .name = "dmac0",
672    .ops = &ios_ops,
673    .parent_names = std_clk_io_parents,
674    .num_parents = ARRAY_SIZE(std_clk_io_parents),
675};
676
677static struct clk_std clk_dmac0 = {
678    .enable_bit = 32,
679    .hw = {
680        .init = &clk_dmac0_init,
681    },
682};
683
684static struct clk_init_data clk_dmac1_init = {
685    .name = "dmac1",
686    .ops = &ios_ops,
687    .parent_names = std_clk_io_parents,
688    .num_parents = ARRAY_SIZE(std_clk_io_parents),
689};
690
691static struct clk_std clk_dmac1 = {
692    .enable_bit = 33,
693    .hw = {
694        .init = &clk_dmac1_init,
695    },
696};
697
698static struct clk_init_data clk_nand_init = {
699    .name = "nand",
700    .ops = &ios_ops,
701    .parent_names = std_clk_io_parents,
702    .num_parents = ARRAY_SIZE(std_clk_io_parents),
703};
704
705static struct clk_std clk_nand = {
706    .enable_bit = 34,
707    .hw = {
708        .init = &clk_nand_init,
709    },
710};
711
712static struct clk_init_data clk_audio_init = {
713    .name = "audio",
714    .ops = &ios_ops,
715    .parent_names = std_clk_io_parents,
716    .num_parents = ARRAY_SIZE(std_clk_io_parents),
717};
718
719static struct clk_std clk_audio = {
720    .enable_bit = 35,
721    .hw = {
722        .init = &clk_audio_init,
723    },
724};
725
726static struct clk_init_data clk_uart0_init = {
727    .name = "uart0",
728    .ops = &ios_ops,
729    .parent_names = std_clk_io_parents,
730    .num_parents = ARRAY_SIZE(std_clk_io_parents),
731};
732
733static struct clk_std clk_uart0 = {
734    .enable_bit = 36,
735    .hw = {
736        .init = &clk_uart0_init,
737    },
738};
739
740static struct clk_init_data clk_uart1_init = {
741    .name = "uart1",
742    .ops = &ios_ops,
743    .parent_names = std_clk_io_parents,
744    .num_parents = ARRAY_SIZE(std_clk_io_parents),
745};
746
747static struct clk_std clk_uart1 = {
748    .enable_bit = 37,
749    .hw = {
750        .init = &clk_uart1_init,
751    },
752};
753
754static struct clk_init_data clk_uart2_init = {
755    .name = "uart2",
756    .ops = &ios_ops,
757    .parent_names = std_clk_io_parents,
758    .num_parents = ARRAY_SIZE(std_clk_io_parents),
759};
760
761static struct clk_std clk_uart2 = {
762    .enable_bit = 38,
763    .hw = {
764        .init = &clk_uart2_init,
765    },
766};
767
768static struct clk_init_data clk_usp0_init = {
769    .name = "usp0",
770    .ops = &ios_ops,
771    .parent_names = std_clk_io_parents,
772    .num_parents = ARRAY_SIZE(std_clk_io_parents),
773};
774
775static struct clk_std clk_usp0 = {
776    .enable_bit = 39,
777    .hw = {
778        .init = &clk_usp0_init,
779    },
780};
781
782static struct clk_init_data clk_usp1_init = {
783    .name = "usp1",
784    .ops = &ios_ops,
785    .parent_names = std_clk_io_parents,
786    .num_parents = ARRAY_SIZE(std_clk_io_parents),
787};
788
789static struct clk_std clk_usp1 = {
790    .enable_bit = 40,
791    .hw = {
792        .init = &clk_usp1_init,
793    },
794};
795
796static struct clk_init_data clk_usp2_init = {
797    .name = "usp2",
798    .ops = &ios_ops,
799    .parent_names = std_clk_io_parents,
800    .num_parents = ARRAY_SIZE(std_clk_io_parents),
801};
802
803static struct clk_std clk_usp2 = {
804    .enable_bit = 41,
805    .hw = {
806        .init = &clk_usp2_init,
807    },
808};
809
810static struct clk_init_data clk_vip_init = {
811    .name = "vip",
812    .ops = &ios_ops,
813    .parent_names = std_clk_io_parents,
814    .num_parents = ARRAY_SIZE(std_clk_io_parents),
815};
816
817static struct clk_std clk_vip = {
818    .enable_bit = 42,
819    .hw = {
820        .init = &clk_vip_init,
821    },
822};
823
824static struct clk_init_data clk_spi0_init = {
825    .name = "spi0",
826    .ops = &ios_ops,
827    .parent_names = std_clk_io_parents,
828    .num_parents = ARRAY_SIZE(std_clk_io_parents),
829};
830
831static struct clk_std clk_spi0 = {
832    .enable_bit = 43,
833    .hw = {
834        .init = &clk_spi0_init,
835    },
836};
837
838static struct clk_init_data clk_spi1_init = {
839    .name = "spi1",
840    .ops = &ios_ops,
841    .parent_names = std_clk_io_parents,
842    .num_parents = ARRAY_SIZE(std_clk_io_parents),
843};
844
845static struct clk_std clk_spi1 = {
846    .enable_bit = 44,
847    .hw = {
848        .init = &clk_spi1_init,
849    },
850};
851
852static struct clk_init_data clk_tsc_init = {
853    .name = "tsc",
854    .ops = &ios_ops,
855    .parent_names = std_clk_io_parents,
856    .num_parents = ARRAY_SIZE(std_clk_io_parents),
857};
858
859static struct clk_std clk_tsc = {
860    .enable_bit = 45,
861    .hw = {
862        .init = &clk_tsc_init,
863    },
864};
865
866static struct clk_init_data clk_i2c0_init = {
867    .name = "i2c0",
868    .ops = &ios_ops,
869    .parent_names = std_clk_io_parents,
870    .num_parents = ARRAY_SIZE(std_clk_io_parents),
871};
872
873static struct clk_std clk_i2c0 = {
874    .enable_bit = 46,
875    .hw = {
876        .init = &clk_i2c0_init,
877    },
878};
879
880static struct clk_init_data clk_i2c1_init = {
881    .name = "i2c1",
882    .ops = &ios_ops,
883    .parent_names = std_clk_io_parents,
884    .num_parents = ARRAY_SIZE(std_clk_io_parents),
885};
886
887static struct clk_std clk_i2c1 = {
888    .enable_bit = 47,
889    .hw = {
890        .init = &clk_i2c1_init,
891    },
892};
893
894static struct clk_init_data clk_pwmc_init = {
895    .name = "pwmc",
896    .ops = &ios_ops,
897    .parent_names = std_clk_io_parents,
898    .num_parents = ARRAY_SIZE(std_clk_io_parents),
899};
900
901static struct clk_std clk_pwmc = {
902    .enable_bit = 48,
903    .hw = {
904        .init = &clk_pwmc_init,
905    },
906};
907
908static struct clk_init_data clk_efuse_init = {
909    .name = "efuse",
910    .ops = &ios_ops,
911    .parent_names = std_clk_io_parents,
912    .num_parents = ARRAY_SIZE(std_clk_io_parents),
913};
914
915static struct clk_std clk_efuse = {
916    .enable_bit = 49,
917    .hw = {
918        .init = &clk_efuse_init,
919    },
920};
921
922static struct clk_init_data clk_pulse_init = {
923    .name = "pulse",
924    .ops = &ios_ops,
925    .parent_names = std_clk_io_parents,
926    .num_parents = ARRAY_SIZE(std_clk_io_parents),
927};
928
929static struct clk_std clk_pulse = {
930    .enable_bit = 50,
931    .hw = {
932        .init = &clk_pulse_init,
933    },
934};
935
936static const char *std_clk_dsp_parents[] = {
937    "dsp",
938};
939
940static struct clk_init_data clk_gps_init = {
941    .name = "gps",
942    .ops = &ios_ops,
943    .parent_names = std_clk_dsp_parents,
944    .num_parents = ARRAY_SIZE(std_clk_dsp_parents),
945};
946
947static struct clk_std clk_gps = {
948    .enable_bit = 1,
949    .hw = {
950        .init = &clk_gps_init,
951    },
952};
953
954static struct clk_init_data clk_mf_init = {
955    .name = "mf",
956    .ops = &ios_ops,
957    .parent_names = std_clk_io_parents,
958    .num_parents = ARRAY_SIZE(std_clk_io_parents),
959};
960
961static struct clk_std clk_mf = {
962    .enable_bit = 2,
963    .hw = {
964        .init = &clk_mf_init,
965    },
966};
967
968static const char *std_clk_sys_parents[] = {
969    "sys",
970};
971
972static struct clk_init_data clk_security_init = {
973    .name = "mf",
974    .ops = &ios_ops,
975    .parent_names = std_clk_sys_parents,
976    .num_parents = ARRAY_SIZE(std_clk_sys_parents),
977};
978
979static struct clk_std clk_security = {
980    .enable_bit = 19,
981    .hw = {
982        .init = &clk_security_init,
983    },
984};
985
986static const char *std_clk_usb_parents[] = {
987    "usb_pll",
988};
989
990static struct clk_init_data clk_usb0_init = {
991    .name = "usb0",
992    .ops = &ios_ops,
993    .parent_names = std_clk_usb_parents,
994    .num_parents = ARRAY_SIZE(std_clk_usb_parents),
995};
996
997static struct clk_std clk_usb0 = {
998    .enable_bit = 16,
999    .hw = {
1000        .init = &clk_usb0_init,
1001    },
1002};
1003
1004static struct clk_init_data clk_usb1_init = {
1005    .name = "usb1",
1006    .ops = &ios_ops,
1007    .parent_names = std_clk_usb_parents,
1008    .num_parents = ARRAY_SIZE(std_clk_usb_parents),
1009};
1010
1011static struct clk_std clk_usb1 = {
1012    .enable_bit = 17,
1013    .hw = {
1014        .init = &clk_usb1_init,
1015    },
1016};
1017
1018static struct of_device_id clkc_ids[] = {
1019    { .compatible = "sirf,prima2-clkc" },
1020    {},
1021};
1022
1023static struct of_device_id rsc_ids[] = {
1024    { .compatible = "sirf,prima2-rsc" },
1025    {},
1026};
1027
1028enum prima2_clk_index {
1029    /* 0 1 2 3 4 5 6 7 8 9 */
1030    rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
1031    mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
1032    spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
1033    usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
1034    usb0, usb1, maxclk,
1035};
1036
1037static __initdata struct clk_hw* prima2_clk_hw_array[maxclk] = {
1038    NULL, /* dummy */
1039    NULL,
1040    &clk_pll1.hw,
1041    &clk_pll2.hw,
1042    &clk_pll3.hw,
1043    &clk_mem.hw,
1044    &clk_sys.hw,
1045    &clk_security.hw,
1046    &clk_dsp.hw,
1047    &clk_gps.hw,
1048    &clk_mf.hw,
1049    &clk_io.hw,
1050    &clk_cpu.hw,
1051    &clk_uart0.hw,
1052    &clk_uart1.hw,
1053    &clk_uart2.hw,
1054    &clk_tsc.hw,
1055    &clk_i2c0.hw,
1056    &clk_i2c1.hw,
1057    &clk_spi0.hw,
1058    &clk_spi1.hw,
1059    &clk_pwmc.hw,
1060    &clk_efuse.hw,
1061    &clk_pulse.hw,
1062    &clk_dmac0.hw,
1063    &clk_dmac1.hw,
1064    &clk_nand.hw,
1065    &clk_audio.hw,
1066    &clk_usp0.hw,
1067    &clk_usp1.hw,
1068    &clk_usp2.hw,
1069    &clk_vip.hw,
1070    &clk_gfx.hw,
1071    &clk_mm.hw,
1072    &clk_lcd.hw,
1073    &clk_vpp.hw,
1074    &clk_mmc01.hw,
1075    &clk_mmc23.hw,
1076    &clk_mmc45.hw,
1077    &usb_pll_clk_hw,
1078    &clk_usb0.hw,
1079    &clk_usb1.hw,
1080};
1081
1082static struct clk *prima2_clks[maxclk];
1083static struct clk_onecell_data clk_data;
1084
1085void __init sirfsoc_of_clk_init(void)
1086{
1087    struct device_node *np;
1088    int i;
1089
1090    np = of_find_matching_node(NULL, rsc_ids);
1091    if (!np)
1092        panic("unable to find compatible rsc node in dtb\n");
1093
1094    sirfsoc_rsc_vbase = of_iomap(np, 0);
1095    if (!sirfsoc_rsc_vbase)
1096        panic("unable to map rsc registers\n");
1097
1098    of_node_put(np);
1099
1100    np = of_find_matching_node(NULL, clkc_ids);
1101    if (!np)
1102        return;
1103
1104    sirfsoc_clk_vbase = of_iomap(np, 0);
1105    if (!sirfsoc_clk_vbase)
1106        panic("unable to map clkc registers\n");
1107
1108    /* These are always available (RTC and 26MHz OSC)*/
1109    prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
1110        CLK_IS_ROOT, 32768);
1111    prima2_clks[osc]= clk_register_fixed_rate(NULL, "osc", NULL,
1112        CLK_IS_ROOT, 26000000);
1113
1114    for (i = pll1; i < maxclk; i++) {
1115        prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
1116        BUG_ON(!prima2_clks[i]);
1117    }
1118    clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
1119    clk_register_clkdev(prima2_clks[io], NULL, "io");
1120    clk_register_clkdev(prima2_clks[mem], NULL, "mem");
1121
1122    clk_data.clks = prima2_clks;
1123    clk_data.clk_num = maxclk;
1124
1125    of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1126}
1127

Archive Download this file



interactive