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

Commit 5b69b870 authored by Deepak Katragadda's avatar Deepak Katragadda
Browse files

clk: msm: gdsc: Check gdsc state before disabling the root clock



The regulator framework uses the is_enabled callback to decide
if the gdsc is on/off. In the case of the mmagic gdscs, since
they are left enabled before kernel boot, this call returns
true even though HLOS hasnt voted for the gdscs itself. This
leads to the next call to disable the gdsc to pass though the
regulator framework. The core clock is disabled in the gdsc
code having assumed that is was enabled during the gdsc enable
call which in reality never happened. This leads to falsely
turning off the core clock. Make a change to disable the clock
only if gdsc_enable was called prior to gdsc_disable.
In addition, make a separate voter for the mmssnoc_axi RPM
resource which the gdsc driver can use exclusively.

CRs-Fixed: 876297
Change-Id: I1c7af5046e599eb3ffecd9283ba9ebc4ed340703
Signed-off-by: default avatarDeepak Katragadda <dkatraga@codeaurora.org>
parent 75d530af
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -3574,7 +3574,7 @@
&gdsc_mmagic_video {
	clock-names = "core_root_clk";
	/* RPM enables the mmagic bimc GDSC when this clk node is voted for. */
	clocks = <&clock_gcc clk_mmssnoc_axi_clk>;
	clocks = <&clock_gcc clk_mmssnoc_gds_clk>;
	qcom,enable-root-clk;
	status = "ok";
};
@@ -3582,7 +3582,7 @@
&gdsc_mmagic_mdss {
	clock-names = "core_root_clk";
	/* RPM enables the mmagic bimc GDSC when this clk node is voted for. */
	clocks = <&clock_gcc clk_mmssnoc_axi_clk>;
	clocks = <&clock_gcc clk_mmssnoc_gds_clk>;
	qcom,enable-root-clk;
	status = "ok";
};
@@ -3590,7 +3590,7 @@
&gdsc_mmagic_camss {
	clock-names = "core_root_clk";
	/* RPM enables the mmagic bimc GDSC when this clk node is voted for. */
	clocks = <&clock_gcc clk_mmssnoc_axi_clk>;
	clocks = <&clock_gcc clk_mmssnoc_gds_clk>;
	qcom,enable-root-clk;
	status = "ok";
};
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ DEFINE_CLK_RPM_SMD(snoc_clk, snoc_a_clk, RPM_BUS_CLK_TYPE, SNOC_CLK_ID, NULL);

DEFINE_CLK_RPM_SMD(mmssnoc_axi_clk, mmssnoc_axi_a_clk, RPM_MMAXI_CLK_TYPE,
				MMXI_CLK_ID, NULL);
static DEFINE_CLK_VOTER(mmssnoc_gds_clk, &mmssnoc_axi_clk.c, LONG_MAX);

DEFINE_CLK_RPM_SMD_BRANCH(aggre1_noc_clk, aggre1_noc_a_clk,
				RPM_AGGR_CLK_TYPE, AGGR1_NOC_ID, 1000);
@@ -3344,6 +3345,7 @@ static struct clk_lookup msm_clocks_rpm_8996[] = {
	CLK_LIST(aggre2_noc_a_clk),
	CLK_LIST(mmssnoc_axi_clk),
	CLK_LIST(mmssnoc_axi_a_clk),
	CLK_LIST(mmssnoc_gds_clk),
	CLK_LIST(bb_clk1),
	CLK_LIST(bb_clk1_ao),
	CLK_LIST(bb_clk1_pin),
+8 −3
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct gdsc {
	bool			force_root_en;
	int			root_clk_idx;
	bool			no_status_check_on_disable;
	bool			is_gdsc_enabled;
	void __iomem		*domain_addr;
};

@@ -184,7 +185,7 @@ static int gdsc_enable(struct regulator_dev *rdev)

	if (sc->force_root_en)
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);

	sc->is_gdsc_enabled = true;
	return 0;
}

@@ -249,9 +250,13 @@ static int gdsc_disable(struct regulator_dev *rdev)
		sc->resets_asserted = true;
	}

	if (sc->root_en || sc->force_root_en)
	/*
	 * Check if gdsc_enable was called for this GDSC. If not, the root
	 * clock will not have been enabled prior to this.
	 */
	if ((sc->is_gdsc_enabled && sc->root_en) || sc->force_root_en)
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);

	sc->is_gdsc_enabled = false;
	return ret;
}

+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@
#define clk_aggre2_noc_a_clk		0xcab67089
#define clk_mmssnoc_axi_clk		0xdb4b31e6
#define clk_mmssnoc_axi_a_clk		0xd4970614
#define clk_mmssnoc_gds_clk		0x06a22afa

#define clk_gpll0			0x1ebe3bc4
#define clk_gpll0_ao			0xa1368304