diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2016-04-08 18:21:55 +0900 |
---|---|---|
committer | Alexandre Courbot <acourbot@nvidia.com> | 2016-06-01 17:24:46 +0900 |
commit | 3872396168ad8932363794b8fa2779354eaa54d6 (patch) | |
tree | 21a9c6580e55752f5f736b4169ff9fa0c6acf72d | |
parent | 88898248c9643c2fe1d5eeb053ea3daaa9c6586c (diff) | |
download | nouveau-3872396168ad8932363794b8fa2779354eaa54d6.tar.gz |
clk/gk20a: add and use MNP programming functions
Add relevant functions to work with the gk20a_pll structure and use them
where they ought to be instead of directly manipulating registers.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
-rw-r--r-- | drm/nouveau/nvkm/subdev/clk/gk20a.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drm/nouveau/nvkm/subdev/clk/gk20a.c index f07cf5b44..80031c0f9 100644 --- a/drm/nouveau/nvkm/subdev/clk/gk20a.c +++ b/drm/nouveau/nvkm/subdev/clk/gk20a.c @@ -136,6 +136,18 @@ gk20a_pllg_read_mnp(struct gk20a_clk *clk, struct gk20a_pll *pll) pll->pl = (val >> GPCPLL_COEFF_P_SHIFT) & MASK(GPCPLL_COEFF_P_WIDTH); } +static void +gk20a_pllg_write_mnp(struct gk20a_clk *clk, const struct gk20a_pll *pll) +{ + struct nvkm_device *device = clk->base.subdev.device; + u32 val; + + val = (pll->m & MASK(GPCPLL_COEFF_M_WIDTH)) << GPCPLL_COEFF_M_SHIFT; + val |= (pll->n & MASK(GPCPLL_COEFF_N_WIDTH)) << GPCPLL_COEFF_N_SHIFT; + val |= (pll->pl & MASK(GPCPLL_COEFF_P_WIDTH)) << GPCPLL_COEFF_P_SHIFT; + nvkm_wr32(device, GPCPLL_COEFF, val); +} + static u32 gk20a_pllg_calc_rate(struct gk20a_clk *clk) { @@ -262,13 +274,13 @@ gk20a_pllg_slide(struct gk20a_clk *clk, u32 n) { struct nvkm_subdev *subdev = &clk->base.subdev; struct nvkm_device *device = subdev->device; - u32 val; + struct gk20a_pll pll; int ret = 0; /* get old coefficients */ - val = nvkm_rd32(device, GPCPLL_COEFF); + gk20a_pllg_read_mnp(clk, &pll); /* do nothing if NDIV is the same */ - if (n == ((val >> GPCPLL_COEFF_N_SHIFT) & MASK(GPCPLL_COEFF_N_WIDTH))) + if (n == pll.n) return 0; /* pll slowdown mode */ @@ -277,11 +289,9 @@ gk20a_pllg_slide(struct gk20a_clk *clk, u32 n) BIT(GPCPLL_NDIV_SLOWDOWN_SLOWDOWN_USING_PLL_SHIFT)); /* new ndiv ready for ramp */ - val = nvkm_rd32(device, GPCPLL_COEFF); - val &= ~(MASK(GPCPLL_COEFF_N_WIDTH) << GPCPLL_COEFF_N_SHIFT); - val |= (n & MASK(GPCPLL_COEFF_N_WIDTH)) << GPCPLL_COEFF_N_SHIFT; + pll.n = n; udelay(1); - nvkm_wr32(device, GPCPLL_COEFF, val); + gk20a_pllg_write_mnp(clk, &pll); /* dynamic ramp to new ndiv */ udelay(1); @@ -377,12 +387,11 @@ _gk20a_pllg_program_mnp(struct gk20a_clk *clk, bool allow_slide) nvkm_debug(subdev, "%s: m=%d n=%d pl=%d\n", __func__, clk->pll.m, clk->pll.n, clk->pll.pl); - n_lo = DIV_ROUND_UP(clk->pll.m * clk->params->min_vco, - clk->parent_rate / KHZ); - val = clk->pll.m << GPCPLL_COEFF_M_SHIFT; - val |= (allow_slide ? n_lo : clk->pll.n) << GPCPLL_COEFF_N_SHIFT; - val |= clk->pll.pl << GPCPLL_COEFF_P_SHIFT; - nvkm_wr32(device, GPCPLL_COEFF, val); + old_pll = clk->pll; + if (allow_slide) + old_pll.n = DIV_ROUND_UP(clk->pll.m * clk->params->min_vco, + clk->parent_rate / KHZ); + gk20a_pllg_write_mnp(clk, &old_pll); gk20a_pllg_enable(clk); |