]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
clk: qcom: gdsc: Enable an RCG before turing on the gdsc
authorRajendra Nayak <rnayak@codeaurora.org>
Thu, 6 Aug 2015 10:37:53 +0000 (16:07 +0530)
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Mon, 11 Jan 2016 09:54:46 +0000 (09:54 +0000)
Some gdsc instances require a certain root clock (RCG) to be turned on
*before* the power domain itself can be turned on. Handle this as part
of the gdsc enable/disable callbacks.

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

index d0a0313d6bef601f229b70782b930ffa7838e1f8..54c2b523f04d1c51578ec6f154e29c448c2b44b6 100644 (file)
@@ -3064,6 +3064,7 @@ static struct gdsc oxili_gdsc = {
                .name = "oxili",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .root_clock = GFX3D_CLK_SRC,
 };
 
 static struct clk_regmap *gcc_msm8916_clocks[] = {
index ec1dfb584d28168e2c96f2477f51e5316d7c1e07..20965fc3ecc2b98efba690fa6b5968fe4943ad8e 100644 (file)
@@ -131,6 +131,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
        if (sc->pwrsts == PWRSTS_ON)
                return gdsc_deassert_reset(sc);
 
+       if (sc->root_clk)
+               clk_prepare_enable(sc->root_clk);
+
        ret = gdsc_toggle_logic(sc, true);
        if (ret)
                return ret;
@@ -152,6 +155,7 @@ static int gdsc_enable(struct generic_pm_domain *domain)
 
 static int gdsc_disable(struct generic_pm_domain *domain)
 {
+       int ret;
        struct gdsc *sc = domain_to_gdsc(domain);
 
        if (sc->pwrsts == PWRSTS_ON)
@@ -160,7 +164,12 @@ 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 (sc->root_clk)
+               clk_disable_unprepare(sc->root_clk);
+
+       return ret;
 }
 
 static inline bool match(unsigned int id, unsigned int *ids, unsigned int count)
@@ -200,7 +209,8 @@ static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev)
                        sc->clks[j] = of_clk_get_from_provider(&clkspec);
                        pm_clk_add_clk(dev, sc->clks[j]);
                        j++;
-               }
+               } else if (clkspec.args[0] == sc->root_clock)
+                       sc->root_clk = of_clk_get_from_provider(&clkspec);
                i++;
        }
        return 0;
index 2fdb332fe95aaac8d1e87e533331c6d51fcdcb19..0b958a60844a5b928e024c3c4bbc1656cfe4917e 100644 (file)
@@ -42,6 +42,8 @@ struct reset_controller_dev;
  * @clocks: ids of clocks associated with the gdsc
  * @clock_count: number of @clocks
  * @clks: clock pointers to gdsc clocks
+ * @root_clock: id of the root clock to be enabled
+ * @root_clk: root clk pointer
  */
 struct gdsc {
        struct generic_pm_domain        pd;
@@ -56,6 +58,8 @@ struct gdsc {
        unsigned int                    *clocks;
        unsigned int                    clock_count;
        struct clk                      **clks;
+       unsigned int                    root_clock;
+       struct clk                      *root_clk;
 };
 
 #ifdef CONFIG_QCOM_GDSC