msm: clock: Support depends in toplevel
Two types of clocks support depends (branches and rcgs) and soon
we'll be adding a third (rpm). Support depends in the core so as
to avoid duplicating that logic all over.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index 0dc0cab..3793ba0 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -1159,7 +1159,6 @@
.root_en_mask = BIT(11),
.ns_reg = EMDH_NS_REG,
.ns_mask = F_MASK_BASIC,
- .depends = &axi_li_adsp_a_clk.c,
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_mdh,
.current_freq = &local_dummy_freq,
@@ -1168,6 +1167,7 @@
.flags = CLKFLAG_MIN | CLKFLAG_MAX,
.ops = &soc_clk_ops_7x30,
CLK_INIT(emdh_clk.c),
+ .depends = &axi_li_adsp_a_clk.c,
},
};
@@ -1180,7 +1180,6 @@
.root_en_mask = BIT(11),
.ns_reg = PMDH_NS_REG,
.ns_mask = F_MASK_BASIC,
- .depends = &axi_li_adsp_a_clk.c,
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_mdh,
.current_freq = &local_dummy_freq,
@@ -1189,6 +1188,7 @@
.flags = CLKFLAG_MIN | CLKFLAG_MAX,
.ops = &soc_clk_ops_7x30,
CLK_INIT(pmdh_clk.c),
+ .depends = &axi_li_adsp_a_clk.c,
},
};
@@ -1227,12 +1227,12 @@
.ns_mask = F_MASK_BASIC | (7 << 12),
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_grp,
- .depends = &axi_grp_2d_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "grp_2d_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(grp_2d_clk.c),
+ .depends = &axi_grp_2d_clk.c,
},
};
@@ -1246,12 +1246,12 @@
.ns_mask = F_MASK_BASIC | (7 << 12),
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_grp,
- .depends = &axi_li_grp_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "grp_3d_src_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(grp_3d_src_clk.c),
+ .depends = &axi_li_grp_clk.c,
},
};
@@ -1423,7 +1423,6 @@
.ns_reg = MDP_NS_REG,
.root_en_mask = BIT(11),
.ns_mask = F_MASK_BASIC,
- .depends = &axi_mdp_clk.c,
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_mdp_core,
.current_freq = &local_dummy_freq,
@@ -1431,6 +1430,7 @@
.dbg_name = "mdp_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(mdp_clk.c),
+ .depends = &axi_mdp_clk.c,
},
};
@@ -1831,12 +1831,12 @@
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_usb,
.current_freq = &local_dummy_freq,
- .depends = &axi_li_adsp_a_clk.c,
.set_rate = set_rate_mnd,
.c = {
.dbg_name = "usb_hs_src_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(usb_hs_src_clk.c),
+ .depends = &axi_li_adsp_a_clk.c,
},
};
@@ -1966,12 +1966,12 @@
.freq_tbl = clk_tbl_vfe_jpeg,
.ns_mask = F_MASK_MND16,
.set_rate = set_rate_mnd,
- .depends = &axi_li_jpeg_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "jpeg_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(jpeg_clk.c),
+ .depends = &axi_li_jpeg_clk.c,
},
};
@@ -1989,12 +1989,12 @@
.freq_tbl = clk_tbl_vfe_jpeg,
.ns_mask = F_MASK_MND16,
.set_rate = set_rate_mnd,
- .depends = &axi_li_vfe_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "vfe_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(vfe_clk.c),
+ .depends = &axi_li_vfe_clk.c,
},
};
@@ -2105,12 +2105,12 @@
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_vpe,
.current_freq = &local_dummy_freq,
- .depends = &axi_vpe_clk.c,
.set_rate = set_rate_mnd,
.c = {
.dbg_name = "vpe_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(vpe_clk.c),
+ .depends = &axi_vpe_clk.c,
},
};
@@ -2141,12 +2141,12 @@
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_mfc,
.current_freq = &local_dummy_freq,
- .depends = &axi_mfc_clk.c,
.set_rate = set_rate_mnd,
.c = {
.dbg_name = "mfc_clk",
.ops = &soc_clk_ops_7x30,
CLK_INIT(mfc_clk.c),
+ .depends = &axi_mfc_clk.c,
},
};
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 23b34d2..187b331 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -544,11 +544,11 @@
.halt_reg = DBG_BUS_VEC_I_REG,
.halt_bit = 26,
},
- .depends = &vcodec_axi_b_clk.c,
.c = {
.dbg_name = "vcodec_axi_a_clk",
.ops = &clk_ops_branch,
CLK_INIT(vcodec_axi_a_clk.c),
+ .depends = &vcodec_axi_b_clk.c,
},
};
@@ -561,11 +561,11 @@
.halt_reg = DBG_BUS_VEC_E_REG,
.halt_bit = 3,
},
- .depends = &vcodec_axi_a_clk.c,
.c = {
.dbg_name = "vcodec_axi_clk",
.ops = &clk_ops_branch,
CLK_INIT(vcodec_axi_clk.c),
+ .depends = &vcodec_axi_a_clk.c,
},
};
@@ -2481,12 +2481,12 @@
.set_rate = set_rate_mnd_banked,
.freq_tbl = clk_tbl_gfx3d,
.bank_masks = &bmnd_info_gfx3d,
- .depends = &gmem_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "gfx3d_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(gfx3d_clk.c),
+ .depends = &gmem_axi_clk.c,
},
};
@@ -2530,12 +2530,12 @@
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_ijpeg,
- .depends = &ijpeg_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "ijpeg_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(ijpeg_clk.c),
+ .depends = &ijpeg_axi_clk.c,
},
};
@@ -2570,12 +2570,12 @@
.ns_mask = (BM(15, 12) | BM(2, 0)),
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_jpegd,
- .depends = &jpegd_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "jpegd_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(jpegd_clk.c),
+ .depends = &jpegd_axi_clk.c,
},
};
@@ -2640,12 +2640,12 @@
.set_rate = set_rate_mnd_banked,
.freq_tbl = clk_tbl_mdp,
.bank_masks = &bmnd_info_mdp,
- .depends = &mdp_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "mdp_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(mdp_clk.c),
+ .depends = &mdp_axi_clk.c,
},
};
@@ -2748,11 +2748,11 @@
.freq_tbl = clk_tbl_rot,
.bank_masks = &bdiv_info_rot,
.current_freq = &local_dummy_freq,
- .depends = &rot_axi_clk.c,
.c = {
.dbg_name = "rot_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(rot_clk.c),
+ .depends = &rot_axi_clk.c,
},
};
@@ -2992,12 +2992,12 @@
.set_rate = set_rate_mnd_banked,
.bank_masks = &bmnd_info_vcodec,
.freq_tbl = clk_tbl_vcodec,
- .depends = &vcodec_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "vcodec_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(vcodec_clk.c),
+ .depends = &vcodec_axi_clk.c,
},
};
@@ -3036,11 +3036,11 @@
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_vpe,
.current_freq = &local_dummy_freq,
- .depends = &vpe_axi_clk.c,
.c = {
.dbg_name = "vpe_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(vpe_clk.c),
+ .depends = &vpe_axi_clk.c,
},
};
@@ -3092,12 +3092,12 @@
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_vfe,
- .depends = &vfe_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "vfe_clk",
.ops = &soc_clk_ops_8960,
CLK_INIT(vfe_clk.c),
+ .depends = &vfe_axi_clk.c,
},
};
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 44276d8..fe56dd9 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -2299,12 +2299,12 @@
.set_rate = set_rate_mnd_banked,
.freq_tbl = clk_tbl_gfx3d,
.bank_masks = &bmnd_info_gfx3d,
- .depends = &gmem_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "gfx3d_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(gfx3d_clk.c),
+ .depends = &gmem_axi_clk.c,
},
};
@@ -2348,12 +2348,12 @@
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_ijpeg,
- .depends = &ijpeg_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "ijpeg_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(ijpeg_clk.c),
+ .depends = &ijpeg_axi_clk.c,
},
};
@@ -2388,12 +2388,12 @@
.ns_mask = (BM(15, 12) | BM(2, 0)),
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_jpegd,
- .depends = &jpegd_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "jpegd_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(jpegd_clk.c),
+ .depends = &jpegd_axi_clk.c,
},
};
@@ -2458,12 +2458,12 @@
.set_rate = set_rate_mnd_banked,
.freq_tbl = clk_tbl_mdp,
.bank_masks = &bmnd_info_mdp,
- .depends = &mdp_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "mdp_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(mdp_clk.c),
+ .depends = &mdp_axi_clk.c,
},
};
@@ -2615,12 +2615,12 @@
.set_rate = set_rate_div_banked,
.freq_tbl = clk_tbl_rot,
.bank_masks = &bdiv_info_rot,
- .depends = &rot_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "rot_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(rot_clk.c),
+ .depends = &rot_axi_clk.c,
},
};
@@ -2794,12 +2794,12 @@
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_vcodec,
- .depends = &vcodec_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "vcodec_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(vcodec_clk.c),
+ .depends = &vcodec_axi_clk.c,
},
};
@@ -2838,12 +2838,12 @@
.ns_mask = (BM(15, 12) | BM(2, 0)),
.set_rate = set_rate_nop,
.freq_tbl = clk_tbl_vpe,
- .depends = &vpe_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "vpe_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(vpe_clk.c),
+ .depends = &vpe_axi_clk.c,
},
};
@@ -2894,12 +2894,12 @@
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_vfe,
- .depends = &vfe_axi_clk.c,
.current_freq = &local_dummy_freq,
.c = {
.dbg_name = "vfe_clk",
.ops = &soc_clk_ops_8x60,
CLK_INIT(vfe_clk.c),
+ .depends = &vfe_axi_clk.c,
},
};
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 6f29803..b7542c8 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -514,17 +514,9 @@
rc = local_vote_sys_vdd(clk->current_freq->sys_vdd);
if (rc)
- goto err_vdd;
- rc = clk_enable(clk->depends);
- if (rc)
- goto err_dep;
+ return rc;
_rcg_clk_enable(clk);
return rc;
-
-err_dep:
- local_unvote_sys_vdd(clk->current_freq->sys_vdd);
-err_vdd:
- return rc;
}
/* Disable a clock and any related power rail. */
@@ -533,11 +525,10 @@
struct rcg_clk *clk = to_rcg_clk(c);
_rcg_clk_disable(clk);
- clk_disable(clk->depends);
local_unvote_sys_vdd(clk->current_freq->sys_vdd);
}
-/* Turn off a clock at boot, without checking refcounts or disabling depends. */
+/* Turn off a clock at boot, without checking refcounts. */
void rcg_clk_auto_off(struct clk *c)
{
_rcg_clk_disable(to_rcg_clk(c));
@@ -911,14 +902,9 @@
int branch_clk_enable(struct clk *clk)
{
- int rc;
unsigned long flags;
struct branch_clk *branch = to_branch_clk(clk);
- rc = clk_enable(branch->depends);
- if (rc)
- return rc;
-
spin_lock_irqsave(&local_clock_reg_lock, flags);
__branch_clk_enable_reg(&branch->b, branch->c.dbg_name);
branch->enabled = true;
@@ -936,8 +922,6 @@
__branch_clk_disable_reg(&branch->b, branch->c.dbg_name);
branch->enabled = false;
spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-
- clk_disable(branch->depends);
}
struct clk *branch_clk_get_parent(struct clk *clk)
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 2455fbf..7367f6e 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -132,7 +132,6 @@
struct clk_freq_tbl *const freq_tbl;
struct clk_freq_tbl *current_freq;
- struct clk *depends;
struct branch b;
struct clk c;
};
@@ -251,7 +250,6 @@
bool enabled;
struct branch b;
struct clk *parent;
- struct clk *depends;
struct clk c;
};
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index a29e9cd..fa84906 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -42,10 +42,16 @@
ret = clk_enable(parent);
if (ret)
goto out;
+ ret = clk_enable(clk->depends);
+ if (ret) {
+ clk_disable(parent);
+ goto out;
+ }
if (clk->ops->enable)
ret = clk->ops->enable(clk);
if (ret) {
+ clk_disable(clk->depends);
clk_disable(parent);
goto out;
}
@@ -81,6 +87,7 @@
if (clk->count == 1) {
if (clk->ops->disable)
clk->ops->disable(clk);
+ clk_disable(clk->depends);
parent = clk_get_parent(clk);
clk_disable(parent);
}
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index db49133..89775b4 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -56,11 +56,13 @@
* struct clk
* @count: enable refcount
* @lock: protects clk_enable()/clk_disable() path and @count
+ * @depends: non-direct parent of clock to enable when this clock is enabled
*/
struct clk {
uint32_t flags;
struct clk_ops *ops;
const char *dbg_name;
+ struct clk *depends;
struct list_head children;
struct list_head siblings;