|
@@ -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_ADSPCKCR 0x0000025c
|
|
|
#define CPG_RCANCKCR 0x00000270
|
|
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
@@ -199,6 +200,51 @@ static struct clk * __init cpg_rcan_clk_register(struct rcar_gen2_cpg *cpg,
|
|
|
return clk;
|
|
|
}
|
|
|
|
|
|
+/* ADSP divisors */
|
|
|
+static const struct clk_div_table cpg_adsp_div_table[] = {
|
|
|
+ { 1, 3 }, { 2, 4 }, { 3, 6 }, { 4, 8 },
|
|
|
+ { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 },
|
|
|
+ { 10, 36 }, { 11, 48 }, { 0, 0 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk * __init cpg_adsp_clk_register(struct rcar_gen2_cpg *cpg)
|
|
|
+{
|
|
|
+ const char *parent_name = "pll1";
|
|
|
+ struct clk_divider *div;
|
|
|
+ struct clk_gate *gate;
|
|
|
+ struct clk *clk;
|
|
|
+
|
|
|
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
|
|
|
+ if (!div)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ div->reg = cpg->reg + CPG_ADSPCKCR;
|
|
|
+ div->width = 4;
|
|
|
+ div->table = cpg_adsp_div_table;
|
|
|
+ div->lock = &cpg->lock;
|
|
|
+
|
|
|
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
|
|
+ if (!gate) {
|
|
|
+ kfree(div);
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+ }
|
|
|
+
|
|
|
+ gate->reg = cpg->reg + CPG_ADSPCKCR;
|
|
|
+ gate->bit_idx = 8;
|
|
|
+ gate->flags = CLK_GATE_SET_TO_DISABLE;
|
|
|
+ gate->lock = &cpg->lock;
|
|
|
+
|
|
|
+ clk = clk_register_composite(NULL, "adsp", &parent_name, 1, NULL, NULL,
|
|
|
+ &div->hw, &clk_divider_ops,
|
|
|
+ &gate->hw, &clk_gate_ops, 0);
|
|
|
+ if (IS_ERR(clk)) {
|
|
|
+ kfree(gate);
|
|
|
+ kfree(div);
|
|
|
+ }
|
|
|
+
|
|
|
+ return clk;
|
|
|
+}
|
|
|
+
|
|
|
/* -----------------------------------------------------------------------------
|
|
|
* CPG Clock Data
|
|
|
*/
|
|
@@ -303,6 +349,8 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
|
|
|
return cpg_z_clk_register(cpg);
|
|
|
} else if (!strcmp(name, "rcan")) {
|
|
|
return cpg_rcan_clk_register(cpg, np);
|
|
|
+ } else if (!strcmp(name, "adsp")) {
|
|
|
+ return cpg_adsp_clk_register(cpg);
|
|
|
} else {
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
}
|