clk: qcom: Handle the clamp_io assert/deassert sequence
authorRajendra Nayak <rnayak@codeaurora.org>
Thu, 20 Oct 2016 09:38:06 +0000 (15:08 +0530)
committerStephen Boyd <sboyd@codeaurora.org>
Wed, 2 Nov 2016 00:24:42 +0000 (17:24 -0700)
Add a flag to mark gdscs which need to support the clamp deassert/assert
before and after the gdsc enable/disable

Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/qcom/gdsc.c
drivers/clk/qcom/gdsc.h

index f12d7b2bddd7061495bcd04a12f76245ed2721d1..925d178ba675982c200cbcdc03f09e7bccd283e5 100644 (file)
@@ -30,6 +30,7 @@
 #define SW_OVERRIDE_MASK       BIT(2)
 #define HW_CONTROL_MASK                BIT(1)
 #define SW_COLLAPSE_MASK       BIT(0)
+#define GMEM_CLAMP_IO_MASK     BIT(0)
 
 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
 #define EN_REST_WAIT_VAL       (0x2 << 20)
@@ -140,6 +141,18 @@ static inline void gdsc_clear_mem_on(struct gdsc *sc)
                regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
 }
 
+static inline void gdsc_deassert_clamp_io(struct gdsc *sc)
+{
+       regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
+                          GMEM_CLAMP_IO_MASK, 0);
+}
+
+static inline void gdsc_assert_clamp_io(struct gdsc *sc)
+{
+       regmap_update_bits(sc->regmap, sc->clamp_io_ctrl,
+                          GMEM_CLAMP_IO_MASK, 1);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
        struct gdsc *sc = domain_to_gdsc(domain);
@@ -148,6 +161,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
        if (sc->pwrsts == PWRSTS_ON)
                return gdsc_deassert_reset(sc);
 
+       if (sc->flags & CLAMP_IO)
+               gdsc_deassert_clamp_io(sc);
+
        ret = gdsc_toggle_logic(sc, true);
        if (ret)
                return ret;
@@ -170,6 +186,7 @@ static int gdsc_enable(struct generic_pm_domain *domain)
 static int gdsc_disable(struct generic_pm_domain *domain)
 {
        struct gdsc *sc = domain_to_gdsc(domain);
+       int ret;
 
        if (sc->pwrsts == PWRSTS_ON)
                return gdsc_assert_reset(sc);
@@ -177,7 +194,14 @@ static int gdsc_disable(struct generic_pm_domain *domain)
        if (sc->pwrsts & PWRSTS_OFF)
                gdsc_clear_mem_on(sc);
 
-       return gdsc_toggle_logic(sc, false);
+       ret = gdsc_toggle_logic(sc, false);
+       if (ret)
+               return ret;
+
+       if (sc->flags & CLAMP_IO)
+               gdsc_assert_clamp_io(sc);
+
+       return 0;
 }
 
 static int gdsc_init(struct gdsc *sc)
index 3bf497c36bdf83b205733fb0201e33e7b103f61d..f011c495752715367dee35e10f2bc59f1568546d 100644 (file)
@@ -39,6 +39,7 @@ struct gdsc {
        struct regmap                   *regmap;
        unsigned int                    gdscr;
        unsigned int                    gds_hw_ctrl;
+       unsigned int                    clamp_io_ctrl;
        unsigned int                    *cxcs;
        unsigned int                    cxc_count;
        const u8                        pwrsts;
@@ -50,6 +51,7 @@ struct gdsc {
 #define PWRSTS_RET_ON          (PWRSTS_RET | PWRSTS_ON)
        const u8                        flags;
 #define VOTABLE                BIT(0)
+#define CLAMP_IO       BIT(1)
        struct reset_controller_dev     *rcdev;
        unsigned int                    *resets;
        unsigned int                    reset_count;