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

Commit d822080d authored by Taniya Das's avatar Taniya Das
Browse files

clk: msm: gdsc: Add API to allow clearing CORE & PERIPH memory



In the cases where periph and core memory bits will be required to be
retained unless modem/low-power-audio subsystem are out of reset.

The boolean property 'qcom,disallow-clear' associated with a GDSC will
allow retaining the memory bits. Once modem & lpass subsystem are out of
reset the api 'gdsc_allow_clear_retention' will be invoked for the reuqired
GDSC from the respective pil client driver.

Change-Id: I331e04c6fd4ea43b10a534d063f288431c158791
Signed-off-by: default avatarTaniya Das <tdas@codeaurora.org>
parent ec7db6c5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ Optional properties:
			Ex. "base", "domain_addr".
 - qcom,no-status-check-on-disable: Do not poll the status bit when GDSC
			is disabled.
 - 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.

Example:
	gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
+17 −4
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ struct gdsc {
	int			root_clk_idx;
	bool			no_status_check_on_disable;
	bool			is_gdsc_enabled;
	bool			allow_clear;
	void __iomem		*domain_addr;
	void __iomem		*hw_ctrl_addr;
	void __iomem		*sw_reset_addr;
@@ -71,6 +72,14 @@ enum gdscr_status {

static DEFINE_MUTEX(gdsc_seq_lock);

void gdsc_allow_clear_retention(struct regulator *regulator)
{
	struct gdsc *sc = regulator_get_drvdata(regulator);

	if (sc)
		sc->allow_clear = true;
}

static int poll_gdsc_status(struct gdsc *sc, enum gdscr_status status)
{
	void __iomem *gdscr;
@@ -254,9 +263,9 @@ static int gdsc_disable(struct regulator_dev *rdev)
	for (i = sc->clock_count-1; i >= 0; i--) {
		if (unlikely(i == sc->root_clk_idx))
			continue;
		if (sc->toggle_mem)
		if (sc->toggle_mem && sc->allow_clear)
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM);
		if (sc->toggle_periph)
		if (sc->toggle_periph && sc->allow_clear)
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
	}

@@ -561,13 +570,17 @@ static int gdsc_probe(struct platform_device *pdev)
		}
	}

	sc->allow_clear = of_property_read_bool(pdev->dev.of_node,
							"qcom,disallow-clear");
	sc->allow_clear = !sc->allow_clear;

	for (i = 0; i < sc->clock_count; i++) {
		if (retain_mem || (regval & PWR_ON_MASK))
		if (retain_mem || (regval & PWR_ON_MASK) || !sc->allow_clear)
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM);

		if (retain_periph || (regval & PWR_ON_MASK))
		if (retain_periph || (regval & PWR_ON_MASK) || !sc->allow_clear)
			clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH);
		else
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
+22 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __GDSC_H
#define __GDSC_H

#include <linux/regulator/consumer.h>

/* Allow the clock memories to be turned off */
void gdsc_allow_clear_retention(struct regulator *regulator);

#endif