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