diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2016-03-23 12:38:26 -0400 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@free-electrons.com> | 2016-04-21 18:29:23 -0400 |
commit | fa4d0ca104bfdcda7b7e2bac855b358f302fd310 (patch) | |
tree | 14c68c6b45413a4281a7d53af3b84564400a4bf1 | |
parent | 7f2ea3847d47d49929d41573a3b26c80ddebbef5 (diff) |
clk: sunxi: Add PLL3 clock
The A10 SoCs and relatives have a PLL controller to drive the PLL3 and
PLL7, clocked from a 3MHz oscillator, that drives the display related
clocks (GPU, display engine, TCON, etc.)
Add a driver for it.
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
-rw-r--r-- | Documentation/devicetree/bindings/clock/sunxi.txt | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi/clk-sun4i-pll3.c | 98 |
3 files changed, 100 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 1bf588e11d46..005a24c6bd74 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt | |||
@@ -10,6 +10,7 @@ Required properties: | |||
10 | "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4 | 10 | "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4 |
11 | "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 | 11 | "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 |
12 | "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23 | 12 | "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23 |
13 | "allwinner,sun4i-a10-pll3-clk" - for the video PLL clock on A10 | ||
13 | "allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80 | 14 | "allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80 |
14 | "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock | 15 | "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock |
15 | "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock | 16 | "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock |
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index 3fd7901d48e4..e2f72797bd9a 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile | |||
@@ -11,6 +11,7 @@ obj-y += clk-a10-ve.o | |||
11 | obj-y += clk-a20-gmac.o | 11 | obj-y += clk-a20-gmac.o |
12 | obj-y += clk-mod0.o | 12 | obj-y += clk-mod0.o |
13 | obj-y += clk-simple-gates.o | 13 | obj-y += clk-simple-gates.o |
14 | obj-y += clk-sun4i-pll3.o | ||
14 | obj-y += clk-sun8i-bus-gates.o | 15 | obj-y += clk-sun8i-bus-gates.o |
15 | obj-y += clk-sun8i-mbus.o | 16 | obj-y += clk-sun8i-mbus.o |
16 | obj-y += clk-sun9i-core.o | 17 | obj-y += clk-sun9i-core.o |
diff --git a/drivers/clk/sunxi/clk-sun4i-pll3.c b/drivers/clk/sunxi/clk-sun4i-pll3.c new file mode 100644 index 000000000000..f66267e77d9c --- /dev/null +++ b/drivers/clk/sunxi/clk-sun4i-pll3.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Maxime Ripard | ||
3 | * | ||
4 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk-provider.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | |||
23 | #define SUN4I_A10_PLL3_GATE_BIT 31 | ||
24 | #define SUN4I_A10_PLL3_DIV_WIDTH 7 | ||
25 | #define SUN4I_A10_PLL3_DIV_SHIFT 0 | ||
26 | |||
27 | static DEFINE_SPINLOCK(sun4i_a10_pll3_lock); | ||
28 | |||
29 | static void __init sun4i_a10_pll3_setup(struct device_node *node) | ||
30 | { | ||
31 | const char *clk_name = node->name, *parent; | ||
32 | struct clk_multiplier *mult; | ||
33 | struct clk_gate *gate; | ||
34 | struct resource res; | ||
35 | void __iomem *reg; | ||
36 | struct clk *clk; | ||
37 | int ret; | ||
38 | |||
39 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
40 | parent = of_clk_get_parent_name(node, 0); | ||
41 | |||
42 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
43 | if (IS_ERR(reg)) { | ||
44 | pr_err("%s: Could not map the clock registers\n", clk_name); | ||
45 | return; | ||
46 | } | ||
47 | |||
48 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
49 | if (!gate) | ||
50 | goto err_unmap; | ||
51 | |||
52 | gate->reg = reg; | ||
53 | gate->bit_idx = SUN4I_A10_PLL3_GATE_BIT; | ||
54 | gate->lock = &sun4i_a10_pll3_lock; | ||
55 | |||
56 | mult = kzalloc(sizeof(*mult), GFP_KERNEL); | ||
57 | if (!mult) | ||
58 | goto err_free_gate; | ||
59 | |||
60 | mult->reg = reg; | ||
61 | mult->shift = SUN4I_A10_PLL3_DIV_SHIFT; | ||
62 | mult->width = SUN4I_A10_PLL3_DIV_WIDTH; | ||
63 | mult->lock = &sun4i_a10_pll3_lock; | ||
64 | |||
65 | clk = clk_register_composite(NULL, clk_name, | ||
66 | &parent, 1, | ||
67 | NULL, NULL, | ||
68 | &mult->hw, &clk_multiplier_ops, | ||
69 | &gate->hw, &clk_gate_ops, | ||
70 | 0); | ||
71 | if (IS_ERR(clk)) { | ||
72 | pr_err("%s: Couldn't register the clock\n", clk_name); | ||
73 | goto err_free_mult; | ||
74 | } | ||
75 | |||
76 | ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
77 | if (ret) { | ||
78 | pr_err("%s: Couldn't register DT provider\n", | ||
79 | clk_name); | ||
80 | goto err_clk_unregister; | ||
81 | } | ||
82 | |||
83 | return; | ||
84 | |||
85 | err_clk_unregister: | ||
86 | clk_unregister_composite(clk); | ||
87 | err_free_mult: | ||
88 | kfree(mult); | ||
89 | err_free_gate: | ||
90 | kfree(gate); | ||
91 | err_unmap: | ||
92 | iounmap(reg); | ||
93 | of_address_to_resource(node, 0, &res); | ||
94 | release_mem_region(res.start, resource_size(&res)); | ||
95 | } | ||
96 | |||
97 | CLK_OF_DECLARE(sun4i_a10_pll3, "allwinner,sun4i-a10-pll3-clk", | ||
98 | sun4i_a10_pll3_setup); | ||