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>
This commit is contained in:
Sergei Shtylyov 2015-01-06 00:25:08 +03:00 committed by Geert Uytterhoeven
parent a2868160f4
commit 90cf0e2b96
2 changed files with 46 additions and 4 deletions

View File

@ -14,10 +14,11 @@ Required Properties:
- reg: Base address and length of the memory resource used by the CPG
- clocks: Reference to the parent clock
- clocks: References to the parent clocks: first to the EXTAL clock, second
to the USB_EXTAL clock
- #clock-cells: Must be 1
- clock-output-names: The names of the clocks. Supported clocks are "main",
"pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
"pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", and "rcan"
Example
@ -27,8 +28,9 @@ Example
compatible = "renesas,r8a7790-cpg-clocks",
"renesas,rcar-gen2-cpg-clocks";
reg = <0 0xe6150000 0 0x1000>;
clocks = <&extal_clk>;
clocks = <&extal_clk &usb_extal_clk>;
#clock-cells = <1>;
clock-output-names = "main", "pll0, "pll1", "pll3",
"lb", "qspi", "sdh", "sd0", "sd1", "z";
"lb", "qspi", "sdh", "sd0", "sd1", "z",
"rcan";
};

View File

@ -33,6 +33,7 @@ struct rcar_gen2_cpg {
#define CPG_FRQCRC 0x000000e0
#define CPG_FRQCRC_ZFC_MASK (0x1f << 8)
#define CPG_FRQCRC_ZFC_SHIFT 8
#define CPG_RCANCKCR 0x00000270
/* -----------------------------------------------------------------------------
* Z Clock
@ -161,6 +162,43 @@ static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg)
return clk;
}
static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg,
struct device_node *np)
{
const char *parent_name = of_clk_get_parent_name(np, 1);
struct clk_fixed_factor *fixed;
struct clk_gate *gate;
struct clk *clk;
fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
if (!fixed)
return ERR_PTR(-ENOMEM);
fixed->mult = 1;
fixed->div = 6;
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate) {
kfree(fixed);
return ERR_PTR(-ENOMEM);
}
gate->reg = cpg->reg + CPG_RCANCKCR;
gate->bit_idx = 8;
gate->flags = CLK_GATE_SET_TO_DISABLE;
gate->lock = &cpg->lock;
clk = clk_register_composite(NULL, "rcan", &parent_name, 1, NULL, NULL,
&fixed->hw, &clk_fixed_factor_ops,
&gate->hw, &clk_gate_ops, 0);
if (IS_ERR(clk)) {
kfree(gate);
kfree(fixed);
}
return clk;
}
/* -----------------------------------------------------------------------------
* CPG Clock Data
*/
@ -263,6 +301,8 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
shift = 0;
} else if (!strcmp(name, "z")) {
return cpg_z_clk_register(cpg);
} else if (!strcmp(name, "rcan")) {
return cpg_rcan_clk_register(cpg, np);
} else {
return ERR_PTR(-EINVAL);
}