if (n == ((val >> GPCPLL_COEFF_N_SHIFT) & MASK(GPCPLL_COEFF_N_WIDTH)))
                return 0;
 
-       /* setup */
-       nvkm_mask(device, GPCPLL_CFG2, 0xff << GPCPLL_CFG2_PLL_STEPA_SHIFT,
-               0x2b << GPCPLL_CFG2_PLL_STEPA_SHIFT);
-       nvkm_mask(device, GPCPLL_CFG3, 0xff << GPCPLL_CFG3_PLL_STEPB_SHIFT,
-               0xb << GPCPLL_CFG3_PLL_STEPB_SHIFT);
-
        /* pll slowdown mode */
        nvkm_mask(device, GPCPLL_NDIV_SLOWDOWN,
                BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT),
 {
 }
 
+int
+gk20a_clk_setup_slide(struct gk20a_clk *clk)
+{
+       struct nvkm_subdev *subdev = &clk->base.subdev;
+       struct nvkm_device *device = subdev->device;
+       u32 step_a, step_b;
+
+       switch (clk->parent_rate) {
+       case 12000000:
+       case 12800000:
+       case 13000000:
+               step_a = 0x2b;
+               step_b = 0x0b;
+               break;
+       case 19200000:
+               step_a = 0x12;
+               step_b = 0x08;
+               break;
+       case 38400000:
+               step_a = 0x04;
+               step_b = 0x05;
+               break;
+       default:
+               nvkm_error(subdev, "invalid parent clock rate %u KHz",
+                          clk->parent_rate / KHZ);
+               return -EINVAL;
+       }
+
+       nvkm_mask(device, GPCPLL_CFG2, 0xff << GPCPLL_CFG2_PLL_STEPA_SHIFT,
+               step_a << GPCPLL_CFG2_PLL_STEPA_SHIFT);
+       nvkm_mask(device, GPCPLL_CFG3, 0xff << GPCPLL_CFG3_PLL_STEPB_SHIFT,
+               step_b << GPCPLL_CFG3_PLL_STEPB_SHIFT);
+
+       return 0;
+}
+
 void
 gk20a_clk_fini(struct nvkm_clk *base)
 {
        nvkm_mask(device, GPC2CLK_OUT, GPC2CLK_OUT_INIT_MASK,
                  GPC2CLK_OUT_INIT_VAL);
 
+       ret = gk20a_clk_setup_slide(clk);
+       if (ret)
+               return ret;
+
        /* Start with lowest frequency */
        base->func->calc(base, &base->func->pstates[0].base);
        ret = base->func->prog(&clk->base);