aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergei Shtylyov <sergei.shtylyov@cogentembedded.com>2015-01-06 17:39:52 -0500
committerGeert Uytterhoeven <geert+renesas@glider.be>2015-01-08 10:14:31 -0500
commit1484276119fb5083a3a8cb0293e763363c317661 (patch)
treea16281f4294d98c55e0cfa65b092c52a3c4a17e6
parent90cf0e2b9660f16f944b892c2d2a08b4e0a551a8 (diff)
clk: shmobile: Add R-Car Gen2 ADSP clock support
Add the ADSP clock support to the R-Car generation 2 CPG driver. This clock gets derived from PLL1. The layout of the ADSPCKCR register is similar to those of the clocks supported by the 'clk-div6' driver but the divider encoding is non-linear, so can't be supported by that driver... Based on the original patch by Konstantin Kozhevnikov <konstantin.kozhevnikov@cogentembedded.com>. 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.txt5
-rw-r--r--drivers/clk/shmobile/clk-rcar-gen2.c48
2 files changed, 51 insertions, 2 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 5b704b5ab8ab..b02944fba9de 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -18,7 +18,8 @@ Required Properties:
18 to the USB_EXTAL clock 18 to the USB_EXTAL clock
19 - #clock-cells: Must be 1 19 - #clock-cells: Must be 1
20 - 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",
21 "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", and "rcan" 21 "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and
22 "adsp"
22 23
23 24
24Example 25Example
@@ -32,5 +33,5 @@ Example
32 #clock-cells = <1>; 33 #clock-cells = <1>;
33 clock-output-names = "main", "pll0, "pll1", "pll3", 34 clock-output-names = "main", "pll0, "pll1", "pll3",
34 "lb", "qspi", "sdh", "sd0", "sd1", "z", 35 "lb", "qspi", "sdh", "sd0", "sd1", "z",
35 "rcan"; 36 "rcan", "adsp";
36 }; 37 };
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
index 08076ee7cd7b..acfb6d7dbd6b 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_ADSPCKCR 0x0000025c
36#define CPG_RCANCKCR 0x00000270 37#define CPG_RCANCKCR 0x00000270
37 38
38/* ----------------------------------------------------------------------------- 39/* -----------------------------------------------------------------------------
@@ -199,6 +200,51 @@ static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg,
199 return clk; 200 return clk;
200} 201}
201 202
203/* ADSP divisors */
204static const struct clk_div_table cpg_adsp_div_table[] = {
205 { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 },
206 { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 },
207 { 10, 36 }, { 11, 48 }, { 0, 0 },
208};
209
210static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg)
211{
212 const char *parent_name = "pll1";
213 struct clk_divider *div;
214 struct clk_gate *gate;
215 struct clk *clk;
216
217 div = kzalloc(sizeof(*div), GFP_KERNEL);
218 if (!div)
219 return ERR_PTR(-ENOMEM);
220
221 div->reg = cpg->reg + CPG_ADSPCKCR;
222 div->width = 4;
223 div->table = cpg_adsp_div_table;
224 div->lock = &cpg->lock;
225
226 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
227 if (!gate) {
228 kfree(div);
229 return ERR_PTR(-ENOMEM);
230 }
231
232 gate->reg = cpg->reg + CPG_ADSPCKCR;
233 gate->bit_idx = 8;
234 gate->flags = CLK_GATE_SET_TO_DISABLE;
235 gate->lock = &cpg->lock;
236
237 clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL,
238 &div->hw, &clk_divider_ops,
239 &gate->hw, &clk_gate_ops, 0);
240 if (IS_ERR(clk)) {
241 kfree(gate);
242 kfree(div);
243 }
244
245 return clk;
246}
247
202/* ----------------------------------------------------------------------------- 248/* -----------------------------------------------------------------------------
203 * CPG Clock Data 249 * CPG Clock Data
204 */ 250 */
@@ -303,6 +349,8 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
303 return cpg_z_clk_register(cpg); 349 return cpg_z_clk_register(cpg);
304 } else if (!strcmp(name, "rcan")) { 350 } else if (!strcmp(name, "rcan")) {
305 return cpg_rcan_clk_register(cpg, np); 351 return cpg_rcan_clk_register(cpg, np);
352 } else if (!strcmp(name, "adsp")) {
353 return cpg_adsp_clk_register(cpg);
306 } else { 354 } else {
307 return ERR_PTR(-EINVAL); 355 return ERR_PTR(-EINVAL);
308 } 356 }