aboutsummaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@codeaurora.org>2016-11-18 17:58:26 +0530
committerStephen Boyd <sboyd@codeaurora.org>2016-11-23 16:41:15 -0800
commit904bb4f5c7de2f40ff31d43d3547d40910e46640 (patch)
tree5268fb9049fcf4576592d6e800c83ecd249bc870 /drivers/clk
parent5e2035b90e7192b48f9615ddfbcc6fef1149ed8a (diff)
clk: qcom: gdsc: Add support for gdscs with HW control
Some GDSCs might support a HW control mode, where in the power domain (gdsc) is brought in and out of low power state (while unsued) without any SW assistance, saving power. Such GDSCs can be configured in a HW control mode when powered on until they are explicitly requested to be powered off by software. Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org> Signed-off-by: Sricharan R <sricharan@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/qcom/gdsc.c18
-rw-r--r--drivers/clk/qcom/gdsc.h1
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 925d178ba675..288186cce0ae 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -56,6 +56,13 @@ static int gdsc_is_enabled(struct gdsc *sc, unsigned int reg)
return !!(val & PWR_ON_MASK);
}
+static int gdsc_hwctrl(struct gdsc *sc, bool en)
+{
+ u32 val = en ? HW_CONTROL_MASK : 0;
+
+ return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, val);
+}
+
static int gdsc_toggle_logic(struct gdsc *sc, bool en)
{
int ret;
@@ -180,6 +187,10 @@ static int gdsc_enable(struct generic_pm_domain *domain)
*/
udelay(1);
+ /* Turn on HW trigger mode if supported */
+ if (sc->flags & HW_CTRL)
+ return gdsc_hwctrl(sc, true);
+
return 0;
}
@@ -191,6 +202,13 @@ static int gdsc_disable(struct generic_pm_domain *domain)
if (sc->pwrsts == PWRSTS_ON)
return gdsc_assert_reset(sc);
+ /* Turn off HW trigger mode if supported */
+ if (sc->flags & HW_CTRL) {
+ ret = gdsc_hwctrl(sc, false);
+ if (ret < 0)
+ return ret;
+ }
+
if (sc->pwrsts & PWRSTS_OFF)
gdsc_clear_mem_on(sc);
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index f011c4957527..39648348e5ec 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -52,6 +52,7 @@ struct gdsc {
const u8 flags;
#define VOTABLE BIT(0)
#define CLAMP_IO BIT(1)
+#define HW_CTRL BIT(2)
struct reset_controller_dev *rcdev;
unsigned int *resets;
unsigned int reset_count;