video: tegra: gk20a: Disable GPU bus clock in power-off
Alex Frid [Fri, 20 Sep 2013 05:11:10 +0000 (22:11 -0700)]
When gk20a is powered off, disable gbus shared user clock and re-enable
it on resume. Still keep direct control of GPCPLL in place as a backup
to prevent system hang in case when gbus clock clients do not balance
enable/disable controls.

Bug 1364240

Change-Id: I50bc1dc10b4b2a405e2c969a08a8ef4ad75de241
Signed-off-by: Alex Frid <afrid@nvidia.com>
(cherry picked from commit 8338eecc4f1775006d106879cc02f582f6fa243a)
Signed-off-by: Ajay Nandakumar <anandakumarm@nvidia.com>

drivers/video/tegra/host/gk20a/clk_gk20a.c

index aa01543..a5ed7d3 100644 (file)
@@ -463,7 +463,7 @@ static int gk20a_init_clk_setup_hw(struct gk20a *g)
                        trim_sys_gpc2clk_out_bypdiv_by31_f());
        gk20a_writel(g, trim_sys_gpc2clk_out_r(), data);
 
-       return clk_program_gpc_pll(g, clk, 0);
+       return 0;
 }
 
 static int set_pll_target(struct gk20a *g, u32 freq, u32 old_freq)
@@ -588,10 +588,6 @@ static int gk20a_clk_register_export_ops(struct gk20a *g)
        ret = tegra_clk_register_export_ops(clk_get_parent(c),
                                            &gk20a_clk_export_ops);
 
-       /* FIXME: this effectively prevents host level clock gating */
-       if (!ret)
-               ret = clk_enable(c);
-
        return ret;
 }
 
@@ -617,7 +613,6 @@ int gk20a_init_clk_support(struct gk20a *g)
 
        err = gk20a_init_clk_setup_hw(g);
        mutex_unlock(&clk->clk_mutex);
-
        if (err)
                return err;
 
@@ -625,6 +620,18 @@ int gk20a_init_clk_support(struct gk20a *g)
        if (err)
                return err;
 
+       /* FIXME: this effectively prevents host level clock gating */
+       err = clk_enable(g->clk.tegra_clk);
+       if (err)
+               return err;
+
+       /* The prev call may not enable PLL if gbus is unbalanced - force it */
+       mutex_lock(&clk->clk_mutex);
+       err = set_pll_freq(g, clk->gpc_pll.freq, clk->gpc_pll.freq);
+       mutex_unlock(&clk->clk_mutex);
+       if (err)
+               return err;
+
        gk20a_writel(g, 0x9080, 0x00100000);
 
        return err;
@@ -654,6 +661,9 @@ int gk20a_suspend_clk_support(struct gk20a *g)
 {
        int ret;
 
+       clk_disable(g->clk.tegra_clk);
+
+       /* The prev call may not disable PLL if gbus is unbalanced - force it */
        mutex_lock(&g->clk.clk_mutex);
        ret = clk_disable_gpcpll(g);
        g->clk.clk_hw_on = false;