Commit a823bb9f authored by Rajendra Nayak's avatar Rajendra Nayak Committed by Stephen Boyd

clk: qcom: gdsc: Add support for votable gdscs

Some gdscs might be controlled via voting registers and might not
really disable when the kernel intends to disable them (due to other
votes keeping them enabled)
Mark these gdscs with a flag for we do not check/wait on a disable
status for these gdscs within the kernel disable callback.

Also at boot, if these GDSCs are found to be ON, we make sure we
vote for them before we inform the genpd framework about their
status. If genpd gets no users, it then disables (removes the vote)
them as part of genpd_poweroff_unused()
Signed-off-by: default avatarRajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 77b1067a
...@@ -66,6 +66,17 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) ...@@ -66,6 +66,17 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
if (ret) if (ret)
return ret; return ret;
/* If disabling votable gdscs, don't poll on status */
if ((sc->flags & VOTABLE) && !en) {
/*
* Add a short delay here to ensure that an enable
* right after it was disabled does not put it in an
* unknown state
*/
udelay(TIMEOUT_US);
return 0;
}
if (sc->gds_hw_ctrl) { if (sc->gds_hw_ctrl) {
status_reg = sc->gds_hw_ctrl; status_reg = sc->gds_hw_ctrl;
/* /*
...@@ -199,6 +210,13 @@ static int gdsc_init(struct gdsc *sc) ...@@ -199,6 +210,13 @@ static int gdsc_init(struct gdsc *sc)
if (on < 0) if (on < 0)
return on; return on;
/*
* Votable GDSCs can be ON due to Vote from other masters.
* If a Votable GDSC is ON, make sure we have a Vote.
*/
if ((sc->flags & VOTABLE) && on)
gdsc_enable(&sc->pd);
if (on || (sc->pwrsts & PWRSTS_RET)) if (on || (sc->pwrsts & PWRSTS_RET))
gdsc_force_mem_on(sc); gdsc_force_mem_on(sc);
else else
......
...@@ -20,13 +20,6 @@ ...@@ -20,13 +20,6 @@
struct regmap; struct regmap;
struct reset_controller_dev; struct reset_controller_dev;
/* Powerdomain allowable state bitfields */
#define PWRSTS_OFF BIT(0)
#define PWRSTS_RET BIT(1)
#define PWRSTS_ON BIT(2)
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
/** /**
* struct gdsc - Globally Distributed Switch Controller * struct gdsc - Globally Distributed Switch Controller
* @pd: generic power domain * @pd: generic power domain
...@@ -49,6 +42,14 @@ struct gdsc { ...@@ -49,6 +42,14 @@ struct gdsc {
unsigned int *cxcs; unsigned int *cxcs;
unsigned int cxc_count; unsigned int cxc_count;
const u8 pwrsts; const u8 pwrsts;
/* Powerdomain allowable state bitfields */
#define PWRSTS_OFF BIT(0)
#define PWRSTS_RET BIT(1)
#define PWRSTS_ON BIT(2)
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
const u8 flags;
#define VOTABLE BIT(0)
struct reset_controller_dev *rcdev; struct reset_controller_dev *rcdev;
unsigned int *resets; unsigned int *resets;
unsigned int reset_count; unsigned int reset_count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment