diff options
author | Mike Turquette <mturquette@linaro.org> | 2013-12-23 00:55:22 -0500 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2013-12-23 00:55:22 -0500 |
commit | 6e1ee9b180a40dbf57ec3204d98b92ac31eff78e (patch) | |
tree | c82a26d10c86faa0df9a8616734e0215668e76ff | |
parent | a5d37d22b548d0c7ff58bf604c951d08eac67b4c (diff) | |
parent | 92ca6a8ce97e07206d474da5477d8da4e41bad6c (diff) |
Merge tag 'renesas-clock-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into clk-next-shmobile2
Renesas ARM based SoC Clock updates for v3.14
Add support for using emev2 SMU clocks with DT
-rw-r--r-- | Documentation/devicetree/bindings/clock/emev2-clock.txt | 98 | ||||
-rw-r--r-- | drivers/clk/shmobile/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/shmobile/clk-emev2.c | 104 |
3 files changed, 203 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/clock/emev2-clock.txt b/Documentation/devicetree/bindings/clock/emev2-clock.txt new file mode 100644 index 000000000000..60bbb1a8c69a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/emev2-clock.txt | |||
@@ -0,0 +1,98 @@ | |||
1 | Device tree Clock bindings for Renesas EMMA Mobile EV2 | ||
2 | |||
3 | This binding uses the common clock binding. | ||
4 | |||
5 | * SMU | ||
6 | System Management Unit described in user's manual R19UH0037EJ1000_SMU. | ||
7 | This is not a clock provider, but clocks under SMU depend on it. | ||
8 | |||
9 | Required properties: | ||
10 | - compatible: Should be "renesas,emev2-smu" | ||
11 | - reg: Address and Size of SMU registers | ||
12 | |||
13 | * SMU_CLKDIV | ||
14 | Function block with an input mux and a divider, which corresponds to | ||
15 | "Serial clock generator" in fig."Clock System Overview" of the manual, | ||
16 | and "xxx frequency division setting register" (XXXCLKDIV) registers. | ||
17 | This makes internal (neither input nor output) clock that is provided | ||
18 | to input of xxxGCLK block. | ||
19 | |||
20 | Required properties: | ||
21 | - compatible: Should be "renesas,emev2-smu-clkdiv" | ||
22 | - reg: Byte offset from SMU base and Bit position in the register | ||
23 | - clocks: Parent clocks. Input clocks as described in clock-bindings.txt | ||
24 | - #clock-cells: Should be <0> | ||
25 | |||
26 | * SMU_GCLK | ||
27 | Clock gating node shown as "Clock stop processing block" in the | ||
28 | fig."Clock System Overview" of the manual. | ||
29 | Registers are "xxx clock gate control register" (XXXGCLKCTRL). | ||
30 | |||
31 | Required properties: | ||
32 | - compatible: Should be "renesas,emev2-smu-gclk" | ||
33 | - reg: Byte offset from SMU base and Bit position in the register | ||
34 | - clocks: Input clock as described in clock-bindings.txt | ||
35 | - #clock-cells: Should be <0> | ||
36 | |||
37 | Example of provider: | ||
38 | |||
39 | usia_u0_sclkdiv: usia_u0_sclkdiv { | ||
40 | compatible = "renesas,emev2-smu-clkdiv"; | ||
41 | reg = <0x610 0>; | ||
42 | clocks = <&pll3_fo>, <&pll4_fo>, <&pll1_fo>, <&osc1_fo>; | ||
43 | #clock-cells = <0>; | ||
44 | }; | ||
45 | |||
46 | usia_u0_sclk: usia_u0_sclk { | ||
47 | compatible = "renesas,emev2-smu-gclk"; | ||
48 | reg = <0x4a0 1>; | ||
49 | clocks = <&usia_u0_sclkdiv>; | ||
50 | #clock-cells = <0>; | ||
51 | }; | ||
52 | |||
53 | Example of consumer: | ||
54 | |||
55 | uart@e1020000 { | ||
56 | compatible = "renesas,em-uart"; | ||
57 | reg = <0xe1020000 0x38>; | ||
58 | interrupts = <0 8 0>; | ||
59 | clocks = <&usia_u0_sclk>; | ||
60 | clock-names = "sclk"; | ||
61 | }; | ||
62 | |||
63 | Example of clock-tree description: | ||
64 | |||
65 | This describes a clock path in the clock tree | ||
66 | c32ki -> pll3_fo -> usia_u0_sclkdiv -> usia_u0_sclk | ||
67 | |||
68 | smu@e0110000 { | ||
69 | compatible = "renesas,emev2-smu"; | ||
70 | reg = <0xe0110000 0x10000>; | ||
71 | #address-cells = <2>; | ||
72 | #size-cells = <0>; | ||
73 | |||
74 | c32ki: c32ki { | ||
75 | compatible = "fixed-clock"; | ||
76 | clock-frequency = <32768>; | ||
77 | #clock-cells = <0>; | ||
78 | }; | ||
79 | pll3_fo: pll3_fo { | ||
80 | compatible = "fixed-factor-clock"; | ||
81 | clocks = <&c32ki>; | ||
82 | clock-div = <1>; | ||
83 | clock-mult = <7000>; | ||
84 | #clock-cells = <0>; | ||
85 | }; | ||
86 | usia_u0_sclkdiv: usia_u0_sclkdiv { | ||
87 | compatible = "renesas,emev2-smu-clkdiv"; | ||
88 | reg = <0x610 0>; | ||
89 | clocks = <&pll3_fo>; | ||
90 | #clock-cells = <0>; | ||
91 | }; | ||
92 | usia_u0_sclk: usia_u0_sclk { | ||
93 | compatible = "renesas,emev2-smu-gclk"; | ||
94 | reg = <0x4a0 1>; | ||
95 | clocks = <&usia_u0_sclkdiv>; | ||
96 | #clock-cells = <0>; | ||
97 | }; | ||
98 | }; | ||
diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/shmobile/Makefile index 706adc6ae70c..9ecef140dba7 100644 --- a/drivers/clk/shmobile/Makefile +++ b/drivers/clk/shmobile/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o | ||
1 | obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o | 2 | obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o |
2 | obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o | 3 | obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o |
3 | obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o | 4 | obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o |
4 | obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o | 5 | obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o |
5 | |||
6 | # for emply built-in.o | 6 | # for emply built-in.o |
7 | obj-n := dummy | 7 | obj-n := dummy |
diff --git a/drivers/clk/shmobile/clk-emev2.c b/drivers/clk/shmobile/clk-emev2.c new file mode 100644 index 000000000000..6c7c929c7765 --- /dev/null +++ b/drivers/clk/shmobile/clk-emev2.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * EMMA Mobile EV2 common clock framework support | ||
3 | * | ||
4 | * Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com> | ||
5 | * Copyright (C) 2012 Magnus Damm | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
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 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_address.h> | ||
25 | |||
26 | /* EMEV2 SMU registers */ | ||
27 | #define USIAU0_RSTCTRL 0x094 | ||
28 | #define USIBU1_RSTCTRL 0x0ac | ||
29 | #define USIBU2_RSTCTRL 0x0b0 | ||
30 | #define USIBU3_RSTCTRL 0x0b4 | ||
31 | #define STI_RSTCTRL 0x124 | ||
32 | #define STI_CLKSEL 0x688 | ||
33 | |||
34 | static DEFINE_SPINLOCK(lock); | ||
35 | |||
36 | /* not pretty, but hey */ | ||
37 | void __iomem *smu_base; | ||
38 | |||
39 | static void __init emev2_smu_write(unsigned long value, int offs) | ||
40 | { | ||
41 | BUG_ON(!smu_base || (offs >= PAGE_SIZE)); | ||
42 | writel_relaxed(value, smu_base + offs); | ||
43 | } | ||
44 | |||
45 | static const struct of_device_id smu_id[] __initconst = { | ||
46 | { .compatible = "renesas,emev2-smu", }, | ||
47 | {}, | ||
48 | }; | ||
49 | |||
50 | static void __init emev2_smu_init(void) | ||
51 | { | ||
52 | struct device_node *np; | ||
53 | |||
54 | np = of_find_matching_node(NULL, smu_id); | ||
55 | BUG_ON(!np); | ||
56 | smu_base = of_iomap(np, 0); | ||
57 | BUG_ON(!smu_base); | ||
58 | of_node_put(np); | ||
59 | |||
60 | /* setup STI timer to run on 32.768 kHz and deassert reset */ | ||
61 | emev2_smu_write(0, STI_CLKSEL); | ||
62 | emev2_smu_write(1, STI_RSTCTRL); | ||
63 | |||
64 | /* deassert reset for UART0->UART3 */ | ||
65 | emev2_smu_write(2, USIAU0_RSTCTRL); | ||
66 | emev2_smu_write(2, USIBU1_RSTCTRL); | ||
67 | emev2_smu_write(2, USIBU2_RSTCTRL); | ||
68 | emev2_smu_write(2, USIBU3_RSTCTRL); | ||
69 | } | ||
70 | |||
71 | static void __init emev2_smu_clkdiv_init(struct device_node *np) | ||
72 | { | ||
73 | u32 reg[2]; | ||
74 | struct clk *clk; | ||
75 | const char *parent_name = of_clk_get_parent_name(np, 0); | ||
76 | if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) | ||
77 | return; | ||
78 | if (!smu_base) | ||
79 | emev2_smu_init(); | ||
80 | clk = clk_register_divider(NULL, np->name, parent_name, 0, | ||
81 | smu_base + reg[0], reg[1], 8, 0, &lock); | ||
82 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
83 | clk_register_clkdev(clk, np->name, NULL); | ||
84 | pr_debug("## %s %s %p\n", __func__, np->name, clk); | ||
85 | } | ||
86 | CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv", | ||
87 | emev2_smu_clkdiv_init); | ||
88 | |||
89 | static void __init emev2_smu_gclk_init(struct device_node *np) | ||
90 | { | ||
91 | u32 reg[2]; | ||
92 | struct clk *clk; | ||
93 | const char *parent_name = of_clk_get_parent_name(np, 0); | ||
94 | if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) | ||
95 | return; | ||
96 | if (!smu_base) | ||
97 | emev2_smu_init(); | ||
98 | clk = clk_register_gate(NULL, np->name, parent_name, 0, | ||
99 | smu_base + reg[0], reg[1], 0, &lock); | ||
100 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | ||
101 | clk_register_clkdev(clk, np->name, NULL); | ||
102 | pr_debug("## %s %s %p\n", __func__, np->name, clk); | ||
103 | } | ||
104 | CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init); | ||