gpu: nvgpu: Don't increase GPCPLL rate before bypass
Alex Frid [Wed, 13 Aug 2014 00:30:08 +0000 (17:30 -0700)]
Do not force GM20b GPCPLL post divider to 1:2 settings before switching
to bypass clock if PLL output frequency is increased as a result. Move
this step under bypass. However, this step is still needed in case when
PLL can be configured without switch to bypass.

Bug 1450787

Change-Id: Iab81b0e5a71f44f738a64e15b05df41fdbd61ebe
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/456505
Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
Tested-by: Seshendra Gadagottu <sgadagottu@nvidia.com>
Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>

drivers/gpu/nvgpu/gm20b/clk_gm20b.c

index e4e5122..561a042 100644 (file)
@@ -368,7 +368,9 @@ pll_locked:
 static int clk_program_gpc_pll(struct gk20a *g, struct clk_gk20a *clk,
                        int allow_slide)
 {
-#if !PLDIV_GLITCHLESS
+#if PLDIV_GLITCHLESS
+       bool skip_bypass;
+#else
        u32 data;
 #endif
        u32 cfg, coeff;
@@ -406,8 +408,9 @@ static int clk_program_gpc_pll(struct gk20a *g, struct clk_gk20a *clk,
         * Limit either FO-to-FO (path A below) or FO-to-bypass (path B below)
         * jump to min_vco/2 by setting post divider >= 1:2.
         */
+       skip_bypass = can_slide && (clk->gpc_pll.M == m);
        coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
-       if ((clk->gpc_pll.PL < 2) || (pl < 2)) {
+       if ((skip_bypass && (clk->gpc_pll.PL < 2)) || (pl < 2)) {
                if (pl != 2) {
                        coeff = set_field(coeff,
                                trim_sys_gpcpll_coeff_pldiv_m(),
@@ -418,7 +421,7 @@ static int clk_program_gpc_pll(struct gk20a *g, struct clk_gk20a *clk,
                }
        }
 
-       if (can_slide && (clk->gpc_pll.M == m))
+       if (skip_bypass)
                goto set_pldiv; /* path A: no need to bypass */
 
        /* path B: bypass if either M changes or PLL is disabled */
@@ -442,7 +445,7 @@ static int clk_program_gpc_pll(struct gk20a *g, struct clk_gk20a *clk,
        nlo = DIV_ROUND_UP(m * gpc_pll_params.min_vco, clk->gpc_pll.clk_in);
        n = allow_slide ? nlo : clk->gpc_pll.N;
 #if PLDIV_GLITCHLESS
-       pl = trim_sys_gpcpll_coeff_pldiv_v(coeff);
+       pl = (clk->gpc_pll.PL < 2) ? 2 : clk->gpc_pll.PL;
 #else
        pl = clk->gpc_pll.PL;
 #endif