diff options
author | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> | 2015-01-05 16:25:08 -0500 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2015-01-08 10:14:31 -0500 |
commit | 90cf0e2b9660f16f944b892c2d2a08b4e0a551a8 (patch) | |
tree | 3b1163eb2c032dd8799224108be2d810efc2ceb3 | |
parent | a2868160f402e0282611cfe72ea0d8b5e57f7aa0 (diff) |
clk: shmobile: Add R-Car Gen2 RCAN clock support
Add the RCAN clock support to the R-Car generation 2 CPG driver. This clock
gets derived from the USB_EXTAL clock, dividing it by 6. The layout of the
RCANCKCR register is similar to those of the clocks supported by the 'clk-div6'
driver but has no divider field, and so can't be supported by that driver...
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
-rw-r--r-- | Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt | 10 | ||||
-rw-r--r-- | drivers/clk/shmobile/clk-rcar-gen2.c | 40 |
2 files changed, 46 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt index fc7ef9946f40..5b704b5ab8ab 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt | |||
@@ -14,10 +14,11 @@ Required Properties: | |||
14 | 14 | ||
15 | - reg: Base address and length of the memory resource used by the CPG | 15 | - reg: Base address and length of the memory resource used by the CPG |
16 | 16 | ||
17 | - clocks: Reference to the parent clock | 17 | - clocks: References to the parent clocks: first to the EXTAL clock, second |
18 | to the USB_EXTAL clock | ||
18 | - #clock-cells: Must be 1 | 19 | - #clock-cells: Must be 1 |
19 | - clock-output-names: The names of the clocks. Supported clocks are "main", | 20 | - clock-output-names: The names of the clocks. Supported clocks are "main", |
20 | "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z" | 21 | "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", and "rcan" |
21 | 22 | ||
22 | 23 | ||
23 | Example | 24 | Example |
@@ -27,8 +28,9 @@ Example | |||
27 | compatible = "renesas,r8a7790-cpg-clocks", | 28 | compatible = "renesas,r8a7790-cpg-clocks", |
28 | "renesas,rcar-gen2-cpg-clocks"; | 29 | "renesas,rcar-gen2-cpg-clocks"; |
29 | reg = <0 0xe6150000 0 0x1000>; | 30 | reg = <0 0xe6150000 0 0x1000>; |
30 | clocks = <&extal_clk>; | 31 | clocks = <&extal_clk &usb_extal_clk>; |
31 | #clock-cells = <1>; | 32 | #clock-cells = <1>; |
32 | clock-output-names = "main", "pll0, "pll1", "pll3", | 33 | clock-output-names = "main", "pll0, "pll1", "pll3", |
33 | "lb", "qspi", "sdh", "sd0", "sd1", "z"; | 34 | "lb", "qspi", "sdh", "sd0", "sd1", "z", |
35 | "rcan"; | ||
34 | }; | 36 | }; |
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c index e996425d06a9..08076ee7cd7b 100644 --- a/drivers/clk/shmobile/clk-rcar-gen2.c +++ b/drivers/clk/shmobile/clk-rcar-gen2.c | |||
@@ -33,6 +33,7 @@ struct rcar_gen2_cpg { | |||
33 | #define CPG_FRQCRC 0x000000e0 | 33 | #define CPG_FRQCRC 0x000000e0 |
34 | #define CPG_FRQCRC_ZFC_MASK (0x1f << 8) | 34 | #define CPG_FRQCRC_ZFC_MASK (0x1f << 8) |
35 | #define CPG_FRQCRC_ZFC_SHIFT 8 | 35 | #define CPG_FRQCRC_ZFC_SHIFT 8 |
36 | #define CPG_RCANCKCR 0x00000270 | ||
36 | 37 | ||
37 | /* ----------------------------------------------------------------------------- | 38 | /* ----------------------------------------------------------------------------- |
38 | * Z Clock | 39 | * Z Clock |
@@ -161,6 +162,43 @@ static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg) | |||
161 | return clk; | 162 | return clk; |
162 | } | 163 | } |
163 | 164 | ||
165 | static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg, | ||
166 | struct device_node *np) | ||
167 | { | ||
168 | const char *parent_name = of_clk_get_parent_name(np, 1); | ||
169 | struct clk_fixed_factor *fixed; | ||
170 | struct clk_gate *gate; | ||
171 | struct clk *clk; | ||
172 | |||
173 | fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); | ||
174 | if (!fixed) | ||
175 | return ERR_PTR(-ENOMEM); | ||
176 | |||
177 | fixed->mult = 1; | ||
178 | fixed->div = 6; | ||
179 | |||
180 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
181 | if (!gate) { | ||
182 | kfree(fixed); | ||
183 | return ERR_PTR(-ENOMEM); | ||
184 | } | ||
185 | |||
186 | gate->reg = cpg->reg + CPG_RCANCKCR; | ||
187 | gate->bit_idx = 8; | ||
188 | gate->flags = CLK_GATE_SET_TO_DISABLE; | ||
189 | gate->lock = &cpg->lock; | ||
190 | |||
191 | clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL, | ||
192 | &fixed->hw, &clk_fixed_factor_ops, | ||
193 | &gate->hw, &clk_gate_ops, 0); | ||
194 | if (IS_ERR(clk)) { | ||
195 | kfree(gate); | ||
196 | kfree(fixed); | ||
197 | } | ||
198 | |||
199 | return clk; | ||
200 | } | ||
201 | |||
164 | /* ----------------------------------------------------------------------------- | 202 | /* ----------------------------------------------------------------------------- |
165 | * CPG Clock Data | 203 | * CPG Clock Data |
166 | */ | 204 | */ |
@@ -263,6 +301,8 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, | |||
263 | shift = 0; | 301 | shift = 0; |
264 | } else if (!strcmp(name, "z")) { | 302 | } else if (!strcmp(name, "z")) { |
265 | return cpg_z_clk_register(cpg); | 303 | return cpg_z_clk_register(cpg); |
304 | } else if (!strcmp(name, "rcan")) { | ||
305 | return cpg_rcan_clk_register(cpg, np); | ||
266 | } else { | 306 | } else { |
267 | return ERR_PTR(-EINVAL); | 307 | return ERR_PTR(-EINVAL); |
268 | } | 308 | } |