aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergei Shtylyov <sergei.shtylyov@cogentembedded.com>2015-01-05 16:25:08 -0500
committerGeert Uytterhoeven <geert+renesas@glider.be>2015-01-08 10:14:31 -0500
commit90cf0e2b9660f16f944b892c2d2a08b4e0a551a8 (patch)
tree3b1163eb2c032dd8799224108be2d810efc2ceb3
parenta2868160f402e0282611cfe72ea0d8b5e57f7aa0 (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.txt10
-rw-r--r--drivers/clk/shmobile/clk-rcar-gen2.c40
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
23Example 24Example
@@ -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
165static 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 }