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 | } |
