Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ef200f6 authored by Junjie Wu's avatar Junjie Wu
Browse files

clock-generic: Use separate list for recursively setting parents



Previous implementation of recursive set parent iterates through all
clocks in mux source list, trying to find the correct parent. This is not
desirable because we only want to recurse on a subset of mux sources.

Split mux source list into parents and rec_parents. Only for sources in
rec_parents, mux_set_parent() will try to recursively search their parent.

Change-Id: I041ac4018105db3459b2135446b948706ead3cae
Signed-off-by: default avatarJunjie Wu <junjiew@codeaurora.org>
parent 7b3692a8
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -2262,11 +2262,15 @@ static struct clk_mux_ops gcc_debug_mux_ops;
static struct mux_clk gcc_debug_mux = {
	.priv = &debug_mux_priv,
	.ops = &gcc_debug_mux_ops,
	.rec_set_par = 1,
	.offset = GCC_DEBUG_CLK_CTL_REG,
	.en_mask = BIT(16),
	.mask = 0x1FF,
	.base = &virt_bases[GCC_BASE],
	MUX_REC_SRC_LIST(
		&kpss_debug_clk.c,
		&mmss_debug_clk.c,
		&rpm_debug_clk.c,
	),
	MUX_SRC_LIST(
		{&kpss_debug_clk.c,		 0x016A},
		{&mmss_debug_clk.c,		 0x002c},
+10 −3
Original line number Diff line number Diff line
@@ -2390,7 +2390,9 @@ static struct mux_clk apss_debug_sec_mux = {
		{&apss_debug_ter_mux.c, 0},
		{&l2_m_clk.c, 1},
	),
	.rec_set_par = 1,
	MUX_REC_SRC_LIST(
		&apss_debug_ter_mux.c,
	),
	.base = &meas_base,
	.c = {
		.dbg_name = "apss_debug_sec_mux",
@@ -2406,7 +2408,9 @@ static struct mux_clk apss_debug_pri_mux = {
	MUX_SRC_LIST(
		{&apss_debug_sec_mux.c, 0},
	),
	.rec_set_par = 1,
	MUX_REC_SRC_LIST(
		&apss_debug_sec_mux.c,
	),
	.base = &meas_base,
	.c = {
		.dbg_name = "apss_debug_pri_mux",
@@ -2446,11 +2450,14 @@ static struct clk_mux_ops gcc_debug_mux_ops;
static struct mux_clk gcc_debug_mux = {
	.priv = &debug_mux_priv,
	.ops = &gcc_debug_mux_ops,
	.rec_set_par = true,
	.offset = GCC_DEBUG_CLK_CTL,
	.en_mask = BIT(16),
	.mask = 0x1FF,
	.base = &virt_bases[GCC_BASE],
	MUX_REC_SRC_LIST(
		&rpm_debug_clk.c,
		&apss_debug_pri_mux.c,
	),
	MUX_SRC_LIST(
		{&rpm_debug_clk.c,			0xFFFF},
		{&apss_debug_pri_mux.c,			0x016A},
+4 −1
Original line number Diff line number Diff line
@@ -2368,10 +2368,13 @@ static int gcc_set_mux_sel(struct mux_clk *clk, int sel)
static struct mux_clk gcc_debug_mux = {
	.priv = &debug_mux_priv,
	.ops = &gcc_debug_mux_ops,
	.rec_set_par = 1,
	.en_mask = BIT(16),
	.mask = 0x3FF,
	.base = &virt_dbgbase,
	MUX_REC_SRC_LIST(
		&debug_mmss_clk.c,
		&debug_rpm_clk.c,
	),
	MUX_SRC_LIST(
		{ &debug_mmss_clk.c, 0x002b },
		{ &debug_rpm_clk.c, 0xffff },
+13 −9
Original line number Diff line number Diff line
@@ -33,24 +33,29 @@ int parent_to_src_sel(struct clk_src *parents, int num_parents, struct clk *p)
	return -EINVAL;
}

static int mux_parent_to_src_sel(struct mux_clk *mux, struct clk *p)
{
	return parent_to_src_sel(mux->parents, mux->num_parents, p);
}

static int mux_set_parent(struct clk *c, struct clk *p)
{
	struct mux_clk *mux = to_mux_clk(c);
	int sel = parent_to_src_sel(mux->parents, mux->num_parents, p);
	int sel = mux_parent_to_src_sel(mux, p);
	struct clk *old_parent;
	int rc = 0, i;
	unsigned long flags;

	if (sel < 0 && mux->rec_set_par) {
		for (i = 0; i < mux->num_parents; i++) {
			rc = clk_set_parent(mux->parents[i].src, p);
	if (sel < 0 && mux->rec_parents) {
		for (i = 0; i < mux->num_rec_parents; i++) {
			rc = clk_set_parent(mux->rec_parents[i], p);
			if (!rc) {
				sel = mux->parents[i].sel;
				/*
				 * This is necessary to ensure prepare/enable
				 * counts get propagated correctly.
				 */
				p = mux->parents[i].src;
				p = mux->rec_parents[i];
				sel = mux_parent_to_src_sel(mux, p);
				break;
			}
		}
@@ -147,7 +152,7 @@ set_par_fail:
	clk_set_rate(new_parent, new_par_curr_rate);
set_rate_fail:
	WARN(mux->ops->set_mux_sel(mux,
		parent_to_src_sel(mux->parents, mux->num_parents, c->parent)),
		mux_parent_to_src_sel(mux, c->parent)),
		"Set rate failed for %s. Also in bad state!\n", c->dbg_name);
	return rc;
}
@@ -187,8 +192,7 @@ static enum handoff mux_handoff(struct clk *c)
	struct mux_clk *mux = to_mux_clk(c);

	c->rate = clk_get_rate(c->parent);
	mux->safe_sel = parent_to_src_sel(mux->parents, mux->num_parents,
							mux->safe_parent);
	mux->safe_sel = mux_parent_to_src_sel(mux, mux->safe_parent);

	if (mux->en_mask && mux->ops && mux->ops->is_enabled)
		return mux->ops->is_enabled(mux)
+13 −3
Original line number Diff line number Diff line
@@ -394,7 +394,12 @@ static struct mux_clk kpss_debug_ter_mux = {
		{&krait2_div_clk.c, 2},
		{&krait3_div_clk.c, 3},
	),
	.rec_set_par = 1,
	MUX_REC_SRC_LIST(
		&krait0_div_clk.c,
		&krait1_div_clk.c,
		&krait2_div_clk.c,
		&krait3_div_clk.c,
	),
	.base = &meas_base,
	.c = {
		.dbg_name = "kpss_debug_ter_mux",
@@ -415,7 +420,10 @@ static struct mux_clk kpss_debug_sec_mux = {
		{&kpss_debug_ter_mux.c, 0},
		{&l2_div_clk.c, 1},
	),
	.rec_set_par = 1,
	MUX_REC_SRC_LIST(
		&kpss_debug_ter_mux.c,
		&l2_div_clk.c,
	),
	.base = &meas_base,
	.c = {
		.dbg_name = "kpss_debug_sec_mux",
@@ -432,7 +440,9 @@ static struct mux_clk kpss_debug_pri_mux = {
	MUX_SRC_LIST(
		{&kpss_debug_sec_mux.c, 0},
	),
	.rec_set_par = 1,
	MUX_REC_SRC_LIST(
		&kpss_debug_sec_mux.c,
	),
	.base = &meas_base,
	.c = {
		.dbg_name = "kpss_debug_pri_mux",
Loading