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

Commit ca0ef175 authored by David Collins's avatar David Collins
Browse files

clk: qcom: gdsc-regulator: add support for skipping GDSC disable



Some GDSCs have side effects when enabled without first
performing a special reset sequence.  It is only feasible for
this sequence to be performed by the always-on processor (AOP)
when it is resuming from system sleep.  Add support for a device
tree flag which can be specified in order to skip physically
disabling a GDSC when regulator_disable() is called.  The AOP
will then ensure that the GDSC is disabled upon entering system
sleep and appropriately reset upon resuming from system sleep.

Also change the is_enabled() callback so that it returns the
GDSC logical enable state instead of the physical enable state
whenever the disable skipping flag is specified.  This ensures
that all dependent regulator and bus requests are made in the
case of disabling and re-enabling a GDSC without entering system
sleep (i.e. when the GDSC shows up as still physically enabled.)

Change-Id: I0eaa3041daa855e458bf97fc58876bc62a236df2
Signed-off-by: default avatarDavid Collins <collinsd@codeaurora.org>
parent a9cdbef8
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -43,6 +43,12 @@ Optional properties:
			Ex. "base", "domain-addr", "sw-reset", "hw-ctrl-addr".
 - qcom,no-status-check-on-disable: Do not poll the status bit when GDSC
			is disabled.
 - qcom,skip-disable:	Boolean flag indicating that the GDSC must not be
			physically disabled upon a software disable request.
			Instead, the GDSC will be disabled by the always-on
			processor (AOP) upon entering system sleep.  The AOP
			will also perform a special reset sequence for the GDSC
			upon resuming from system sleep.
 - qcom,disallow-clear: Presence denotes the periph & core memory will not be
			cleared, unless the required subsystem does not invoke
			the api which will allow clearing the bits.
+16 −1
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ struct gdsc {
	bool			root_en;
	bool			force_root_en;
	bool			no_status_check_on_disable;
	bool			skip_disable;
	bool			is_gdsc_enabled;
	bool			allow_clear;
	bool			reset_aon;
@@ -150,6 +151,13 @@ static int gdsc_is_enabled(struct regulator_dev *rdev)
	int ret;
	bool is_enabled = false;

	/*
	 * Return the logical GDSC enable state given that it will only be
	 * physically disabled by AOP during system sleep.
	 */
	if (sc->skip_disable)
		return sc->is_gdsc_enabled;

	if (!sc->toggle_logic)
		return !sc->resets_asserted;

@@ -418,7 +426,12 @@ static int gdsc_disable(struct regulator_dev *rdev)
	/* Delay to account for staggered memory powerdown. */
	udelay(1);

	if (sc->toggle_logic) {
	if (sc->skip_disable) {
		/*
		 * Don't change the GDSCR register state on disable.  AOP will
		 * handle this during system sleep.
		 */
	} else if (sc->toggle_logic) {
		regmap_read(sc->regmap, REG_OFFSET, &regval);
		regval |= SW_COLLAPSE_MASK;
		regmap_write(sc->regmap, REG_OFFSET, regval);
@@ -831,6 +844,8 @@ static int gdsc_probe(struct platform_device *pdev)
	sc->no_status_check_on_disable =
			of_property_read_bool(pdev->dev.of_node,
					"qcom,no-status-check-on-disable");
	sc->skip_disable = of_property_read_bool(pdev->dev.of_node,
					"qcom,skip-disable");
	retain_mem = of_property_read_bool(pdev->dev.of_node,
					    "qcom,retain-mem");
	sc->toggle_mem = !retain_mem;