]>
Commit | Line | Data |
---|---|---|
c7bb4fc1 JJ |
1 | /* |
2 | * MOXA ART SoCs clock driver. | |
3 | * | |
4 | * Copyright (C) 2013 Jonas Jensen | |
5 | * | |
6 | * Jonas Jensen <[email protected]> | |
7 | * | |
8 | * This file is licensed under the terms of the GNU General Public | |
9 | * License version 2. This program is licensed "as is" without any | |
10 | * warranty of any kind, whether express or implied. | |
11 | */ | |
12 | ||
67bb5408 | 13 | #include <linux/clk.h> |
c7bb4fc1 JJ |
14 | #include <linux/clk-provider.h> |
15 | #include <linux/io.h> | |
16 | #include <linux/of_address.h> | |
17 | #include <linux/clkdev.h> | |
18 | ||
61ad23a1 | 19 | static void __init moxart_of_pll_clk_init(struct device_node *node) |
c7bb4fc1 JJ |
20 | { |
21 | static void __iomem *base; | |
22 | struct clk *clk, *ref_clk; | |
23 | unsigned int mul; | |
24 | const char *name = node->name; | |
25 | const char *parent_name; | |
26 | ||
27 | of_property_read_string(node, "clock-output-names", &name); | |
28 | parent_name = of_clk_get_parent_name(node, 0); | |
29 | ||
30 | base = of_iomap(node, 0); | |
31 | if (!base) { | |
32 | pr_err("%s: of_iomap failed\n", node->full_name); | |
33 | return; | |
34 | } | |
35 | ||
36 | mul = readl(base + 0x30) >> 3 & 0x3f; | |
37 | iounmap(base); | |
38 | ||
39 | ref_clk = of_clk_get(node, 0); | |
40 | if (IS_ERR(ref_clk)) { | |
41 | pr_err("%s: of_clk_get failed\n", node->full_name); | |
42 | return; | |
43 | } | |
44 | ||
45 | clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); | |
46 | if (IS_ERR(clk)) { | |
47 | pr_err("%s: failed to register clock\n", node->full_name); | |
48 | return; | |
49 | } | |
50 | ||
51 | clk_register_clkdev(clk, NULL, name); | |
52 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | |
53 | } | |
54 | CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", | |
55 | moxart_of_pll_clk_init); | |
56 | ||
61ad23a1 | 57 | static void __init moxart_of_apb_clk_init(struct device_node *node) |
c7bb4fc1 JJ |
58 | { |
59 | static void __iomem *base; | |
60 | struct clk *clk, *pll_clk; | |
61 | unsigned int div, val; | |
62 | unsigned int div_idx[] = { 2, 3, 4, 6, 8}; | |
63 | const char *name = node->name; | |
64 | const char *parent_name; | |
65 | ||
66 | of_property_read_string(node, "clock-output-names", &name); | |
67 | parent_name = of_clk_get_parent_name(node, 0); | |
68 | ||
69 | base = of_iomap(node, 0); | |
70 | if (!base) { | |
71 | pr_err("%s: of_iomap failed\n", node->full_name); | |
72 | return; | |
73 | } | |
74 | ||
75 | val = readl(base + 0xc) >> 4 & 0x7; | |
76 | iounmap(base); | |
77 | ||
78 | if (val > 4) | |
79 | val = 0; | |
80 | div = div_idx[val] * 2; | |
81 | ||
82 | pll_clk = of_clk_get(node, 0); | |
83 | if (IS_ERR(pll_clk)) { | |
84 | pr_err("%s: of_clk_get failed\n", node->full_name); | |
85 | return; | |
86 | } | |
87 | ||
88 | clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div); | |
89 | if (IS_ERR(clk)) { | |
90 | pr_err("%s: failed to register clock\n", node->full_name); | |
91 | return; | |
92 | } | |
93 | ||
94 | clk_register_clkdev(clk, NULL, name); | |
95 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | |
96 | } | |
97 | CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock", | |
98 | moxart_of_apb_clk_init); |